1965 lines
431 KiB
HTML
1965 lines
431 KiB
HTML
<!DOCTYPE html> <html> <head> <title>acorn.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> acorn.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> <p>Acorn is a tiny, fast JavaScript parser written in JavaScript.</p>
|
|
|
|
<p>Acorn was written by Marijn Haverbeke and various contributors and
|
|
released under an MIT license. The Unicode regexps (for identifiers
|
|
and whitespace) were taken from <a href="http://esprima.org">Esprima</a> by
|
|
Ariya Hidayat.</p>
|
|
|
|
<p>Git repositories for Acorn are available at</p>
|
|
|
|
<pre><code>http://marijnhaverbeke.nl/git/acorn
|
|
https://github.com/marijnh/acorn.git
|
|
</code></pre>
|
|
|
|
<p>Please use the <a href="https://github.com/marijnh/acorn/issues">github bug tracker</a> to report issues.</p>
|
|
|
|
<p>This file defines the main parser interface. The library also comes
|
|
with a <a href="acorn_loose.js">error-tolerant parser</a> and an
|
|
<a href="util/walk.js">abstract syntax tree walker</a>, defined in other files.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">root</span><span class="p">,</span> <span class="nx">mod</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">exports</span> <span class="o">==</span> <span class="s2">"object"</span> <span class="o">&&</span> <span class="k">typeof</span> <span class="nx">module</span> <span class="o">==</span> <span class="s2">"object"</span><span class="p">)</span> <span class="k">return</span> <span class="nx">mod</span><span class="p">(</span><span class="nx">exports</span><span class="p">);</span> <span class="c1">// CommonJS</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">define</span> <span class="o">==</span> <span class="s2">"function"</span> <span class="o">&&</span> <span class="nx">define</span><span class="p">.</span><span class="nx">amd</span><span class="p">)</span> <span class="k">return</span> <span class="nx">define</span><span class="p">([</span><span class="s2">"exports"</span><span class="p">],</span> <span class="nx">mod</span><span class="p">);</span> <span class="c1">// AMD</span>
|
|
<span class="nx">mod</span><span class="p">(</span><span class="nx">root</span><span class="p">.</span><span class="nx">acorn</span> <span class="o">||</span> <span class="p">(</span><span class="nx">root</span><span class="p">.</span><span class="nx">acorn</span> <span class="o">=</span> <span class="p">{}));</span> <span class="c1">// Plain browser env</span>
|
|
<span class="p">})(</span><span class="k">this</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">exports</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="s2">"use strict"</span><span class="p">;</span>
|
|
|
|
<span class="nx">exports</span><span class="p">.</span><span class="nx">version</span> <span class="o">=</span> <span class="s2">"0.7.1"</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <p>The main exported interface (under <code>self.acorn</code> when in the
|
|
browser) is a <code>parse</code> function that takes a code string and
|
|
returns an abstract syntax tree as specified by <a href="https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API">Mozilla parser
|
|
API</a>, with the caveat that inline XML is not recognized.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">options</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">inputLen</span><span class="p">,</span> <span class="nx">sourceFile</span><span class="p">;</span>
|
|
|
|
<span class="nx">exports</span><span class="p">.</span><span class="nx">parse</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inpt</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">input</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">inpt</span><span class="p">);</span> <span class="nx">inputLen</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
|
<span class="nx">setOptions</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
|
|
<span class="nx">initTokenState</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">parseTopLevel</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">program</span><span class="p">);</span>
|
|
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <p>A second optional argument can be given to further configure
|
|
the parser process. These options are recognized:</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">defaultOptions</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">defaultOptions</span> <span class="o">=</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <p><code>ecmaVersion</code> indicates the ECMAScript version to parse. Must
|
|
be either 3, or 5, or 6. This influences support for strict
|
|
mode, the set of reserved words, support for getters and
|
|
setters and other features.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ecmaVersion</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <p>Turn on <code>strictSemicolons</code> to prevent the parser from doing
|
|
automatic semicolon insertion.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">strictSemicolons</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <p>When <code>allowTrailingCommas</code> is false, the parser will not allow
|
|
trailing commas in array and object literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">allowTrailingCommas</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <p>By default, reserved words are not enforced. Enable
|
|
<code>forbidReserved</code> to enforce them. When this option has the
|
|
value "everywhere", reserved words and keywords can also not be
|
|
used as property names.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">forbidReserved</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <p>When enabled, a return at the top level is not considered an
|
|
error.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">allowReturnOutsideFunction</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">¶</a> </div> <p>When <code>locations</code> is on, <code>loc</code> properties holding objects with
|
|
<code>start</code> and <code>end</code> properties in <code>{line, column}</code> form (with
|
|
line being 1-based and column 0-based) will be attached to the
|
|
nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">locations</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</a> </div> <p>A function can be passed as <code>onToken</code> option, which will
|
|
cause Acorn to call that function with object in the same
|
|
format as tokenize() returns. Note that you are not
|
|
allowed to call the parser from the callback—that will
|
|
corrupt its internal state.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">onToken</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</a> </div> <p>A function can be passed as <code>onComment</code> option, which will
|
|
cause Acorn to call that function with <code>(block, text, start,
|
|
end)</code> parameters whenever a comment is skipped. <code>block</code> is a
|
|
boolean indicating whether this is a block (<code>/* */</code>) comment,
|
|
<code>text</code> is the content of the comment, and <code>start</code> and <code>end</code> are
|
|
character offsets that denote the start and end of the comment.
|
|
When the <code>locations</code> option is on, two more parameters are
|
|
passed, the full <code>{line, column}</code> locations of the start and
|
|
end of the comments. Note that you are not allowed to call the
|
|
parser from the callback—that will corrupt its internal state.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">onComment</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">¶</a> </div> <p>Nodes have their start and end characters offsets recorded in
|
|
<code>start</code> and <code>end</code> properties (directly on the node, rather than
|
|
the <code>loc</code> object, which holds line/column data. To also add a
|
|
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=745678">semi-standardized</a> <code>range</code> property holding a <code>[start,
|
|
end]</code> array with the same numbers, set the <code>ranges</code> option to
|
|
<code>true</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ranges</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">¶</a> </div> <p>It is possible to parse multiple files into a single AST by
|
|
passing the tree produced by parsing the first file as
|
|
<code>program</code> option in subsequent parses. This will add the
|
|
toplevel forms of the parsed file to the <code>Program</code> (top) node
|
|
of an existing parse tree.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">program</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">¶</a> </div> <p>When <code>locations</code> is on, you can pass this to record the source
|
|
file in every node's <code>loc</code> object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">sourceFile</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</a> </div> <p>This value, if given, is stored in every node, whether
|
|
<code>locations</code> is on or off.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">directSourceFile</span><span class="o">:</span> <span class="kc">null</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">setOptions</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">options</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">opt</span> <span class="k">in</span> <span class="nx">defaultOptions</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">has</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">opt</span><span class="p">))</span>
|
|
<span class="nx">options</span><span class="p">[</span><span class="nx">opt</span><span class="p">]</span> <span class="o">=</span> <span class="nx">defaultOptions</span><span class="p">[</span><span class="nx">opt</span><span class="p">];</span>
|
|
<span class="nx">sourceFile</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sourceFile</span> <span class="o">||</span> <span class="kc">null</span><span class="p">;</span>
|
|
|
|
<span class="nx">isKeyword</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">?</span> <span class="nx">isEcma6Keyword</span> <span class="o">:</span> <span class="nx">isEcma5AndLessKeyword</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</a> </div> <p>The <code>getLineInfo</code> function is mostly useful when the
|
|
<code>locations</code> option is off (for performance reasons) and you
|
|
want to find the line/column position for a given character
|
|
offset. <code>input</code> should be the code string that the offset refers
|
|
into.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">getLineInfo</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">getLineInfo</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">offset</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">line</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">cur</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;;)</span> <span class="p">{</span>
|
|
<span class="nx">lineBreak</span><span class="p">.</span><span class="nx">lastIndex</span> <span class="o">=</span> <span class="nx">cur</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">match</span> <span class="o">&&</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o"><</span> <span class="nx">offset</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">line</span><span class="p">;</span>
|
|
<span class="nx">cur</span> <span class="o">=</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">line</span><span class="o">:</span> <span class="nx">line</span><span class="p">,</span> <span class="nx">column</span><span class="o">:</span> <span class="nx">offset</span> <span class="o">-</span> <span class="nx">cur</span><span class="p">};</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">getCurrentToken</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">token</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="nx">type</span><span class="o">:</span> <span class="nx">tokType</span><span class="p">,</span>
|
|
<span class="nx">value</span><span class="o">:</span> <span class="nx">tokVal</span><span class="p">,</span>
|
|
<span class="nx">start</span><span class="o">:</span> <span class="nx">tokStart</span><span class="p">,</span>
|
|
<span class="nx">end</span><span class="o">:</span> <span class="nx">tokEnd</span>
|
|
<span class="p">};</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">token</span><span class="p">.</span><span class="nx">startLoc</span> <span class="o">=</span> <span class="nx">tokStartLoc</span><span class="p">;</span>
|
|
<span class="nx">token</span><span class="p">.</span><span class="nx">endLoc</span> <span class="o">=</span> <span class="nx">tokEndLoc</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">token</span><span class="p">;</span>
|
|
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</a> </div> <p>Acorn is organized as a tokenizer and a recursive-descent parser.
|
|
The <code>tokenize</code> export provides an interface to the tokenizer.
|
|
Because the tokenizer is optimized for being efficiently used by
|
|
the Acorn parser itself, this interface is somewhat crude and not
|
|
very modular. Performing another parse or call to <code>tokenize</code> will
|
|
reset the internal state, and invalidate existing tokenizers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">exports</span><span class="p">.</span><span class="nx">tokenize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inpt</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">input</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">inpt</span><span class="p">);</span> <span class="nx">inputLen</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
|
<span class="nx">setOptions</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
|
|
<span class="nx">initTokenState</span><span class="p">();</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">getToken</span><span class="p">(</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">lastEnd</span> <span class="o">=</span> <span class="nx">tokEnd</span><span class="p">;</span>
|
|
<span class="nx">readToken</span><span class="p">(</span><span class="nx">forceRegexp</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">getCurrentToken</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">getToken</span><span class="p">.</span><span class="nx">jumpTo</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">pos</span><span class="p">,</span> <span class="nx">reAllowed</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">pos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">tokCurLine</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">lastIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">match</span><span class="p">;</span>
|
|
<span class="k">while</span> <span class="p">((</span><span class="nx">match</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">))</span> <span class="o">&&</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o"><</span> <span class="nx">pos</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="nx">reAllowed</span><span class="p">;</span>
|
|
<span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="p">};</span>
|
|
<span class="k">return</span> <span class="nx">getToken</span><span class="p">;</span>
|
|
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">¶</a> </div> <p>State is kept in (closure-)global variables. We already saw the
|
|
<code>options</code>, <code>input</code>, and <code>inputLen</code> variables above.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</a> </div> <p>The current position of the tokenizer in the input.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokPos</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</a> </div> <p>The start and end offsets of the current token.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokStart</span><span class="p">,</span> <span class="nx">tokEnd</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</a> </div> <p>When <code>options.locations</code> is true, these hold objects
|
|
containing the tokens start and end line/column pairs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokStartLoc</span><span class="p">,</span> <span class="nx">tokEndLoc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">¶</a> </div> <p>The type and value of the current token. Token types are objects,
|
|
named by variables against which they can be compared, and
|
|
holding properties that describe them (indicating, for example,
|
|
the precedence of an infix operator, and the original name of a
|
|
keyword token). The kind of value that's held in <code>tokVal</code> depends
|
|
on the type of the token. For literals, it is the literal value,
|
|
for operators, the operator name, and so on.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokType</span><span class="p">,</span> <span class="nx">tokVal</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">¶</a> </div> <p>Internal state for the tokenizer. To distinguish between division
|
|
operators and regular expressions, it remembers whether the last
|
|
token was one that is allowed to be followed by an expression.
|
|
(If it is, a slash is probably a regexp, if it isn't it's a
|
|
division operator. See the <code>parseStatement</code> function for a
|
|
caveat.)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokRegexpAllowed</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">¶</a> </div> <p>When <code>options.locations</code> is true, these are used to keep
|
|
track of the current line, and know when a new line has been
|
|
entered.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokCurLine</span><span class="p">,</span> <span class="nx">tokLineStart</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">¶</a> </div> <p>These store the position of the previous token, which is useful
|
|
when finishing a node and assigning its <code>end</code> position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lastStart</span><span class="p">,</span> <span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">lastEndLoc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">¶</a> </div> <p>This is the parser's state. <code>inFunction</code> is used to reject
|
|
<code>return</code> statements outside of functions, <code>inGenerator</code> to
|
|
reject <code>yield</code>s outside of generators, <code>labels</code> to verify
|
|
that <code>break</code> and <code>continue</code> have somewhere to jump to, and
|
|
<code>strict</code> indicates whether strict mode is on.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">inFunction</span><span class="p">,</span> <span class="nx">inGenerator</span><span class="p">,</span> <span class="nx">labels</span><span class="p">,</span> <span class="nx">strict</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">¶</a> </div> <p>This counter is used for checking that arrow expressions did
|
|
not contain nested parentheses in argument list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">metParenL</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">¶</a> </div> <p>This is used by parser for detecting if it's inside ES6
|
|
Template String. If it is, it should treat '$' as prefix before
|
|
'{expression}' and everything else as string literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">inTemplate</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">¶</a> </div> <p>This function is used to raise exceptions on parse errors. It
|
|
takes an offset integer (into the current <code>input</code>) to indicate
|
|
the location of the error, attaches the position to the end
|
|
of the error message, and then raises a <code>SyntaxError</code> with that
|
|
message.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">pos</span><span class="p">,</span> <span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">loc</span> <span class="o">=</span> <span class="nx">getLineInfo</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">pos</span><span class="p">);</span>
|
|
<span class="nx">message</span> <span class="o">+=</span> <span class="s2">" ("</span> <span class="o">+</span> <span class="nx">loc</span><span class="p">.</span><span class="nx">line</span> <span class="o">+</span> <span class="s2">":"</span> <span class="o">+</span> <span class="nx">loc</span><span class="p">.</span><span class="nx">column</span> <span class="o">+</span> <span class="s2">")"</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">err</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SyntaxError</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
|
|
<span class="nx">err</span><span class="p">.</span><span class="nx">pos</span> <span class="o">=</span> <span class="nx">pos</span><span class="p">;</span> <span class="nx">err</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="nx">loc</span><span class="p">;</span> <span class="nx">err</span><span class="p">.</span><span class="nx">raisedAt</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">throw</span> <span class="nx">err</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <p>Reused empty array added for node fields that are always empty.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">empty</span> <span class="o">=</span> <span class="p">[];</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</a> </div> <h2>Token types</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">¶</a> </div> <p>The assignment of fine-grained, information-carrying type objects
|
|
allows the tokenizer to store the information it has about a
|
|
token in a way that is very cheap for the parser to look up.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">¶</a> </div> <p>All token type variables start with an underscore, to make them
|
|
easy to recognize.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</a> </div> <p>These are the general types. The <code>type</code> property is only used to
|
|
make them recognizeable when debugging.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_num</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"num"</span><span class="p">},</span> <span class="nx">_regexp</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"regexp"</span><span class="p">},</span> <span class="nx">_string</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"string"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_name</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"name"</span><span class="p">},</span> <span class="nx">_eof</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"eof"</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</a> </div> <p>Keyword tokens. The <code>keyword</code> property (also used in keyword-like
|
|
operators) indicates that the token originated from an
|
|
identifier-like word, which is used when parsing property names.</p>
|
|
|
|
<p>The <code>beforeExpr</code> property is used to disambiguate between regular
|
|
expressions and divisions. It is set on all token types that can
|
|
be followed by an expression (thus, a slash after them would be a
|
|
regular expression).</p>
|
|
|
|
<p><code>isLoop</code> marks a keyword as starting a loop, which is important
|
|
to know when parsing a label, in order to allow or disallow
|
|
continue jumps to that label.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_break</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"break"</span><span class="p">},</span> <span class="nx">_case</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"case"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_catch</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"catch"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_continue</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"continue"</span><span class="p">},</span> <span class="nx">_debugger</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"debugger"</span><span class="p">},</span> <span class="nx">_default</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"default"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_do</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"do"</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_else</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"else"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_finally</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"finally"</span><span class="p">},</span> <span class="nx">_for</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"for"</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_function</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"function"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_if</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"if"</span><span class="p">},</span> <span class="nx">_return</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"return"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_switch</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"switch"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_throw</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"throw"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_try</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"try"</span><span class="p">},</span> <span class="nx">_var</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"var"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_let</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"let"</span><span class="p">},</span> <span class="nx">_const</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"const"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_while</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"while"</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_with</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"with"</span><span class="p">},</span> <span class="nx">_new</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"new"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_this</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"this"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_class</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"class"</span><span class="p">},</span> <span class="nx">_extends</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"extends"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_export</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"export"</span><span class="p">},</span> <span class="nx">_import</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"import"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_yield</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"yield"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</a> </div> <p>The keywords that denote values.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_null</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"null"</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">null</span><span class="p">},</span> <span class="nx">_true</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"true"</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_false</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"false"</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">false</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">¶</a> </div> <p>Some keywords are treated as regular operators. <code>in</code> sometimes
|
|
(when parsing <code>for</code>) needs to be tested against specifically, so
|
|
we assign a variable name to it for quick comparing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_in</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"in"</span><span class="p">,</span> <span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">¶</a> </div> <p>Map keyword names to token types.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">keywordTypes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"break"</span><span class="o">:</span> <span class="nx">_break</span><span class="p">,</span> <span class="s2">"case"</span><span class="o">:</span> <span class="nx">_case</span><span class="p">,</span> <span class="s2">"catch"</span><span class="o">:</span> <span class="nx">_catch</span><span class="p">,</span>
|
|
<span class="s2">"continue"</span><span class="o">:</span> <span class="nx">_continue</span><span class="p">,</span> <span class="s2">"debugger"</span><span class="o">:</span> <span class="nx">_debugger</span><span class="p">,</span> <span class="s2">"default"</span><span class="o">:</span> <span class="nx">_default</span><span class="p">,</span>
|
|
<span class="s2">"do"</span><span class="o">:</span> <span class="nx">_do</span><span class="p">,</span> <span class="s2">"else"</span><span class="o">:</span> <span class="nx">_else</span><span class="p">,</span> <span class="s2">"finally"</span><span class="o">:</span> <span class="nx">_finally</span><span class="p">,</span> <span class="s2">"for"</span><span class="o">:</span> <span class="nx">_for</span><span class="p">,</span>
|
|
<span class="s2">"function"</span><span class="o">:</span> <span class="nx">_function</span><span class="p">,</span> <span class="s2">"if"</span><span class="o">:</span> <span class="nx">_if</span><span class="p">,</span> <span class="s2">"return"</span><span class="o">:</span> <span class="nx">_return</span><span class="p">,</span> <span class="s2">"switch"</span><span class="o">:</span> <span class="nx">_switch</span><span class="p">,</span>
|
|
<span class="s2">"throw"</span><span class="o">:</span> <span class="nx">_throw</span><span class="p">,</span> <span class="s2">"try"</span><span class="o">:</span> <span class="nx">_try</span><span class="p">,</span> <span class="s2">"var"</span><span class="o">:</span> <span class="nx">_var</span><span class="p">,</span> <span class="s2">"let"</span><span class="o">:</span> <span class="nx">_let</span><span class="p">,</span> <span class="s2">"const"</span><span class="o">:</span> <span class="nx">_const</span><span class="p">,</span>
|
|
<span class="s2">"while"</span><span class="o">:</span> <span class="nx">_while</span><span class="p">,</span> <span class="s2">"with"</span><span class="o">:</span> <span class="nx">_with</span><span class="p">,</span>
|
|
<span class="s2">"null"</span><span class="o">:</span> <span class="nx">_null</span><span class="p">,</span> <span class="s2">"true"</span><span class="o">:</span> <span class="nx">_true</span><span class="p">,</span> <span class="s2">"false"</span><span class="o">:</span> <span class="nx">_false</span><span class="p">,</span> <span class="s2">"new"</span><span class="o">:</span> <span class="nx">_new</span><span class="p">,</span> <span class="s2">"in"</span><span class="o">:</span> <span class="nx">_in</span><span class="p">,</span>
|
|
<span class="s2">"instanceof"</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"instanceof"</span><span class="p">,</span> <span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="s2">"this"</span><span class="o">:</span> <span class="nx">_this</span><span class="p">,</span>
|
|
<span class="s2">"typeof"</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"typeof"</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span>
|
|
<span class="s2">"void"</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"void"</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span>
|
|
<span class="s2">"delete"</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">"delete"</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span>
|
|
<span class="s2">"class"</span><span class="o">:</span> <span class="nx">_class</span><span class="p">,</span> <span class="s2">"extends"</span><span class="o">:</span> <span class="nx">_extends</span><span class="p">,</span>
|
|
<span class="s2">"export"</span><span class="o">:</span> <span class="nx">_export</span><span class="p">,</span> <span class="s2">"import"</span><span class="o">:</span> <span class="nx">_import</span><span class="p">,</span> <span class="s2">"yield"</span><span class="o">:</span> <span class="nx">_yield</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">¶</a> </div> <p>Punctuation token types. Again, the <code>type</code> property is purely for debugging.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_bracketL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"["</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bracketR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"]"</span><span class="p">},</span> <span class="nx">_braceL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"{"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_braceR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"}"</span><span class="p">},</span> <span class="nx">_parenL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"("</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_parenR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">")"</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_comma</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">","</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_semi</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">";"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_colon</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">":"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_dot</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"."</span><span class="p">},</span> <span class="nx">_ellipsis</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"..."</span><span class="p">},</span> <span class="nx">_question</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"?"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_arrow</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"=>"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bquote</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"`"</span><span class="p">},</span> <span class="nx">_dollarBraceL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">"${"</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">¶</a> </div> <p>Operators. These carry several kinds of properties to help the
|
|
parser use them properly (the presence of these properties is
|
|
what categorizes them as operators).</p>
|
|
|
|
<p><code>binop</code>, when present, specifies that this operator is a binary
|
|
operator, and will refer to its precedence.</p>
|
|
|
|
<p><code>prefix</code> and <code>postfix</code> mark the operator as a prefix or postfix
|
|
unary operator. <code>isUpdate</code> specifies that the node produced by
|
|
the operator should be of type UpdateExpression rather than
|
|
simply UnaryExpression (<code>++</code> and <code>--</code>).</p>
|
|
|
|
<p><code>isAssign</code> marks all of <code>=</code>, <code>+=</code>, <code>-=</code> etcetera, which act as
|
|
binary operators with a very low precedence, that should result
|
|
in AssignmentExpression nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_slash</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_eq</span> <span class="o">=</span> <span class="p">{</span><span class="nx">isAssign</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_assign</span> <span class="o">=</span> <span class="p">{</span><span class="nx">isAssign</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_incDec</span> <span class="o">=</span> <span class="p">{</span><span class="nx">postfix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">isUpdate</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_prefix</span> <span class="o">=</span> <span class="p">{</span><span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_logicalOR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_logicalAND</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_bitwiseOR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_bitwiseXOR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">4</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_bitwiseAND</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_equality</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">6</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_relational</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_bitShift</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">8</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_plusMin</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">9</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
|
|
<span class="kd">var</span> <span class="nx">_modulo</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">¶</a> </div> <p>'*' may be multiply or have special meaning in ES6</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_star</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">¶</a> </div> <p>Provide access to the token types for external users of the
|
|
tokenizer.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">exports</span><span class="p">.</span><span class="nx">tokTypes</span> <span class="o">=</span> <span class="p">{</span><span class="nx">bracketL</span><span class="o">:</span> <span class="nx">_bracketL</span><span class="p">,</span> <span class="nx">bracketR</span><span class="o">:</span> <span class="nx">_bracketR</span><span class="p">,</span> <span class="nx">braceL</span><span class="o">:</span> <span class="nx">_braceL</span><span class="p">,</span> <span class="nx">braceR</span><span class="o">:</span> <span class="nx">_braceR</span><span class="p">,</span>
|
|
<span class="nx">parenL</span><span class="o">:</span> <span class="nx">_parenL</span><span class="p">,</span> <span class="nx">parenR</span><span class="o">:</span> <span class="nx">_parenR</span><span class="p">,</span> <span class="nx">comma</span><span class="o">:</span> <span class="nx">_comma</span><span class="p">,</span> <span class="nx">semi</span><span class="o">:</span> <span class="nx">_semi</span><span class="p">,</span> <span class="nx">colon</span><span class="o">:</span> <span class="nx">_colon</span><span class="p">,</span>
|
|
<span class="nx">dot</span><span class="o">:</span> <span class="nx">_dot</span><span class="p">,</span> <span class="nx">ellipsis</span><span class="o">:</span> <span class="nx">_ellipsis</span><span class="p">,</span> <span class="nx">question</span><span class="o">:</span> <span class="nx">_question</span><span class="p">,</span> <span class="nx">slash</span><span class="o">:</span> <span class="nx">_slash</span><span class="p">,</span> <span class="nx">eq</span><span class="o">:</span> <span class="nx">_eq</span><span class="p">,</span>
|
|
<span class="nx">name</span><span class="o">:</span> <span class="nx">_name</span><span class="p">,</span> <span class="nx">eof</span><span class="o">:</span> <span class="nx">_eof</span><span class="p">,</span> <span class="nx">num</span><span class="o">:</span> <span class="nx">_num</span><span class="p">,</span> <span class="nx">regexp</span><span class="o">:</span> <span class="nx">_regexp</span><span class="p">,</span> <span class="nx">string</span><span class="o">:</span> <span class="nx">_string</span><span class="p">,</span>
|
|
<span class="nx">arrow</span><span class="o">:</span> <span class="nx">_arrow</span><span class="p">,</span> <span class="nx">bquote</span><span class="o">:</span> <span class="nx">_bquote</span><span class="p">,</span> <span class="nx">dollarBraceL</span><span class="o">:</span> <span class="nx">_dollarBraceL</span><span class="p">};</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">kw</span> <span class="k">in</span> <span class="nx">keywordTypes</span><span class="p">)</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">tokTypes</span><span class="p">[</span><span class="s2">"_"</span> <span class="o">+</span> <span class="nx">kw</span><span class="p">]</span> <span class="o">=</span> <span class="nx">keywordTypes</span><span class="p">[</span><span class="nx">kw</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">¶</a> </div> <p>This is a trick taken from Esprima. It turns out that, on
|
|
non-Chrome browsers, to check whether a string is in a set, a
|
|
predicate containing a big ugly <code>switch</code> statement is faster than
|
|
a regular expression, and on Chrome the two are about on par.
|
|
This function uses <code>eval</code> (non-lexical) to produce such a
|
|
predicate from a space-separated string of words.</p>
|
|
|
|
<p>It starts by sorting the words by length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="nx">words</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">words</span> <span class="o">=</span> <span class="nx">words</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span> <span class="nx">cats</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">out</span><span class="o">:</span> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">words</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o"><</span> <span class="nx">cats</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">j</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">cats</span><span class="p">[</span><span class="nx">j</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span> <span class="o">==</span> <span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">cats</span><span class="p">[</span><span class="nx">j</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
|
|
<span class="k">continue</span> <span class="nx">out</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">cats</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">]]);</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">function</span> <span class="nx">compareTo</span><span class="p">(</span><span class="nx">arr</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">arr</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nx">f</span> <span class="o">+=</span> <span class="s2">"return str === "</span> <span class="o">+</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="s2">";"</span><span class="p">;</span>
|
|
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">"switch(str){"</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="nx">f</span> <span class="o">+=</span> <span class="s2">"case "</span> <span class="o">+</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="o">+</span> <span class="s2">":"</span><span class="p">;</span>
|
|
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">"return true}return false;"</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">¶</a> </div> <p>When there are more than three length categories, an outer
|
|
switch first dispatches on the lengths, to save on comparisons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">cats</span><span class="p">.</span><span class="nx">length</span> <span class="o">></span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">cats</span><span class="p">.</span><span class="nx">sort</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;});</span>
|
|
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">"switch(str.length){"</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">cats</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">cat</span> <span class="o">=</span> <span class="nx">cats</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
|
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">"case "</span> <span class="o">+</span> <span class="nx">cat</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span> <span class="o">+</span> <span class="s2">":"</span><span class="p">;</span>
|
|
<span class="nx">compareTo</span><span class="p">(</span><span class="nx">cat</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">"}"</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">¶</a> </div> <p>Otherwise, simply generate a flat <code>switch</code> statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">compareTo</span><span class="p">(</span><span class="nx">words</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="s2">"str"</span><span class="p">,</span> <span class="nx">f</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">¶</a> </div> <p>The ECMAScript 3 reserved word list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isReservedWord3</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">¶</a> </div> <p>ECMAScript 5 reserved words.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isReservedWord5</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">"class enum extends super const export import"</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">¶</a> </div> <p>The additional reserved words in strict mode.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isStrictReservedWord</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">"implements interface let package private protected public static yield"</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">¶</a> </div> <p>The forbidden variable names in strict mode.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isStrictBadIdWord</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">"eval arguments"</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">¶</a> </div> <p>And the keywords.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ecma5AndLessKeywords</span> <span class="o">=</span> <span class="s2">"break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"</span><span class="p">;</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">isEcma5AndLessKeyword</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="nx">ecma5AndLessKeywords</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">isEcma6Keyword</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="nx">ecma5AndLessKeywords</span> <span class="o">+</span> <span class="s2">" let const class extends export import yield"</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">isKeyword</span> <span class="o">=</span> <span class="nx">isEcma5AndLessKeyword</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</a> </div> <h2>Character categories</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">¶</a> </div> <p>Big ugly regular expressions that match characters in the
|
|
whitespace, identifier, and identifier-start categories. These
|
|
are only applied when a character is found to actually have a
|
|
code point above 128.
|
|
Generated by <code>tools/generate-identifier-regex.js</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">nonASCIIwhitespace</span> <span class="o">=</span> <span class="sr">/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">=</span> <span class="s2">"\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\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\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\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\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"</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">nonASCIIidentifierChars</span> <span class="o">=</span> <span class="s2">"\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19B0-\u19C0\u19C8\u19C9\u19D0-\u19D9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F"</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">nonASCIIidentifierStart</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">"["</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">+</span> <span class="s2">"]"</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">nonASCIIidentifier</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">"["</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierChars</span> <span class="o">+</span> <span class="s2">"]"</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">¶</a> </div> <p>Whether a single character denotes a newline.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">newline</span> <span class="o">=</span> <span class="sr">/[\n\r\u2028\u2029]/</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">¶</a> </div> <p>Matches a whole line break (where CRLF is considered a single
|
|
line break). Used to count lines.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lineBreak</span> <span class="o">=</span> <span class="sr">/\r\n|[\n\r\u2028\u2029]/g</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">¶</a> </div> <p>Test whether a given character code starts an identifier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isIdentifierStart</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">isIdentifierStart</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">65</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">36</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">91</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">97</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">95</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">123</span><span class="p">)</span><span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">code</span> <span class="o">>=</span> <span class="mh">0xaa</span> <span class="o">&&</span> <span class="nx">nonASCIIidentifierStart</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span>
|
|
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">¶</a> </div> <p>Test whether a given character is part of an identifier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isIdentifierChar</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">isIdentifierChar</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">48</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">36</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">58</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">65</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">91</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">97</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">95</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><</span> <span class="mi">123</span><span class="p">)</span><span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">code</span> <span class="o">>=</span> <span class="mh">0xaa</span> <span class="o">&&</span> <span class="nx">nonASCIIidentifier</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span>
|
|
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">¶</a> </div> <h2>Tokenizer</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">¶</a> </div> <p>These are used when <code>options.locations</code> is on, for the
|
|
<code>tokStartLoc</code> and <code>tokEndLoc</code> properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">Position</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">line</span> <span class="o">=</span> <span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">column</span> <span class="o">=</span> <span class="nx">tokPos</span> <span class="o">-</span> <span class="nx">tokLineStart</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">¶</a> </div> <p>Reset the token state. Used at the start of a parse.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">initTokenState</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">tokCurLine</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">tokLineStart</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
|
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">metParenL</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
|
<span class="nx">inTemplate</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">¶</a> </div> <p>Called at the end of every token. Sets <code>tokEnd</code>, <code>tokVal</code>, and
|
|
<code>tokRegexpAllowed</code>, and skips the space after the token, so that
|
|
the next one's <code>tokStart</code> will point at the right position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">val</span><span class="p">,</span> <span class="nx">shouldSkipSpace</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">tokEnd</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">tokEndLoc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">;</span>
|
|
<span class="nx">tokType</span> <span class="o">=</span> <span class="nx">type</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">shouldSkipSpace</span> <span class="o">!==</span> <span class="kc">false</span><span class="p">)</span> <span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="nx">tokVal</span> <span class="o">=</span> <span class="nx">val</span><span class="p">;</span>
|
|
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="nx">type</span><span class="p">.</span><span class="nx">beforeExpr</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">onToken</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">options</span><span class="p">.</span><span class="nx">onToken</span><span class="p">(</span><span class="nx">getCurrentToken</span><span class="p">());</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">skipBlockComment</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">startLoc</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span> <span class="o">&&</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locations</span> <span class="o">&&</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">,</span> <span class="nx">end</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">"*/"</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">end</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"Unterminated comment"</span><span class="p">);</span>
|
|
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">end</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">lineBreak</span><span class="p">.</span><span class="nx">lastIndex</span> <span class="o">=</span> <span class="nx">start</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">match</span><span class="p">;</span>
|
|
<span class="k">while</span> <span class="p">((</span><span class="nx">match</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">))</span> <span class="o">&&</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o"><</span> <span class="nx">tokPos</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span><span class="p">)</span>
|
|
<span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">end</span><span class="p">),</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">,</span>
|
|
<span class="nx">startLoc</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locations</span> <span class="o">&&</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">skipLineComment</span><span class="p">(</span><span class="nx">startSkip</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">startLoc</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span> <span class="o">&&</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locations</span> <span class="o">&&</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+=</span><span class="nx">startSkip</span><span class="p">);</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o"><</span> <span class="nx">inputLen</span> <span class="o">&&</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">10</span> <span class="o">&&</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">13</span> <span class="o">&&</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">8232</span> <span class="o">&&</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">8233</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span><span class="p">)</span>
|
|
<span class="nx">options</span><span class="p">.</span><span class="nx">onComment</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span> <span class="o">+</span> <span class="nx">startSkip</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">),</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">,</span>
|
|
<span class="nx">startLoc</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locations</span> <span class="o">&&</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">¶</a> </div> <p>Called at the start of the parse and after every token. Skips
|
|
whitespace and comments, and.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">skipSpace</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o"><</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">32</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ' '</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">13</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">10</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">8232</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">8233</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">></span> <span class="mi">8</span> <span class="o">&&</span> <span class="nx">ch</span> <span class="o"><</span> <span class="mi">14</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">47</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '/'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">42</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '*'</span>
|
|
<span class="nx">skipBlockComment</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">47</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '/'</span>
|
|
<span class="nx">skipLineComment</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">160</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '\xa0'</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">>=</span> <span class="mi">5760</span> <span class="o">&&</span> <span class="nx">nonASCIIwhitespace</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">)))</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">¶</a> </div> <h3>Token reading</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">¶</a> </div> <p>This is the function that is called to fetch the next token. It
|
|
is somewhat obscure, because it works in character codes rather
|
|
than characters, and because operator parsing has been inlined
|
|
into it.</p>
|
|
|
|
<p>All in the name of speed.</p>
|
|
|
|
<p>The <code>forceRegexp</code> parameter is used in the one case where the
|
|
<code>tokRegexpAllowed</code> trick does not work. See <code>parseStatement</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readToken_dot</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">>=</span> <span class="mi">48</span> <span class="o">&&</span> <span class="nx">next</span> <span class="o"><=</span> <span class="mi">57</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readNumber</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">next2</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">46</span> <span class="o">&&</span> <span class="nx">next2</span> <span class="o">===</span> <span class="mi">46</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 46 = dot '.'</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">3</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_ellipsis</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_dot</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_slash</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// '/'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokRegexpAllowed</span><span class="p">)</span> <span class="p">{</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">readRegexp</span><span class="p">();}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_slash</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_mult_modulo</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '%*'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">42</span> <span class="o">?</span> <span class="nx">_star</span> <span class="o">:</span> <span class="nx">_modulo</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_pipe_amp</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '|&'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">124</span> <span class="o">?</span> <span class="nx">_logicalOR</span> <span class="o">:</span> <span class="nx">_logicalAND</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">124</span> <span class="o">?</span> <span class="nx">_bitwiseOR</span> <span class="o">:</span> <span class="nx">_bitwiseAND</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_caret</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// '^'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bitwiseXOR</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_plus_min</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '+-'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">==</span> <span class="mi">45</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">62</span> <span class="o">&&</span>
|
|
<span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">)))</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">¶</a> </div> <p>A <code>--></code> line comment</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">skipLineComment</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
|
|
<span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">readToken</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_incDec</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_plusMin</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_lt_gt</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '<>'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">size</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">size</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">62</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">62</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="nx">size</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="nx">size</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bitShift</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">==</span> <span class="mi">33</span> <span class="o">&&</span> <span class="nx">code</span> <span class="o">==</span> <span class="mi">60</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">45</span> <span class="o">&&</span>
|
|
<span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="o">==</span> <span class="mi">45</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">¶</a> </div> <p><code><!--</code>, an XML-style comment that should be interpreted as a line comment</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">skipLineComment</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
|
|
<span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">readToken</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span>
|
|
<span class="nx">size</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_relational</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken_eq_excl</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '=!', '=>'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_equality</span><span class="p">,</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">&&</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">62</span> <span class="o">&&</span> <span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '=>'</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_arrow</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="nx">_eq</span> <span class="o">:</span> <span class="nx">_prefix</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">¶</a> </div> <p>Get token inside ES6 template (special rules work there).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">getTemplateToken</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">¶</a> </div> <p>'`' and '${' have special meanings, but they should follow
|
|
string (can be empty)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">96</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '`'</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bquote</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">36</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">===</span> <span class="mi">123</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '${'</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_dollarBraceL</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">125</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '}'</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">,</span> <span class="kc">undefined</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">¶</a> </div> <p>anything else is considered string literal</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">readTmplString</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">getTokenFromCode</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">¶</a> </div> <p>The interpretation of a dot depends on whether it is followed
|
|
by a digit or another two dots.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">46</span><span class="o">:</span> <span class="c1">// '.'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_dot</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">¶</a> </div> <p>Punctuation tokens.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">40</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">41</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">59</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">44</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">91</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bracketL</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">93</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">123</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">125</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">58</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="mi">63</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_question</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">96</span><span class="o">:</span> <span class="c1">// '`'</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bquote</span><span class="p">,</span> <span class="kc">undefined</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">case</span> <span class="mi">48</span><span class="o">:</span> <span class="c1">// '0'</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">120</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">88</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readRadixNumber</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span> <span class="c1">// '0x', '0X' - hex number</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">111</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">79</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readRadixNumber</span><span class="p">(</span><span class="mi">8</span><span class="p">);</span> <span class="c1">// '0o', '0O' - octal number</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">98</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">66</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readRadixNumber</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span> <span class="c1">// '0b', '0B' - binary number</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">¶</a> </div> <p>Anything else beginning with a digit is an integer, octal
|
|
number, or float.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">49</span><span class="o">:</span> <span class="k">case</span> <span class="mi">50</span><span class="o">:</span> <span class="k">case</span> <span class="mi">51</span><span class="o">:</span> <span class="k">case</span> <span class="mi">52</span><span class="o">:</span> <span class="k">case</span> <span class="mi">53</span><span class="o">:</span> <span class="k">case</span> <span class="mi">54</span><span class="o">:</span> <span class="k">case</span> <span class="mi">55</span><span class="o">:</span> <span class="k">case</span> <span class="mi">56</span><span class="o">:</span> <span class="k">case</span> <span class="mi">57</span><span class="o">:</span> <span class="c1">// 1-9</span>
|
|
<span class="k">return</span> <span class="nx">readNumber</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">¶</a> </div> <p>Quotes produce strings.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">34</span><span class="o">:</span> <span class="k">case</span> <span class="mi">39</span><span class="o">:</span> <span class="c1">// '"', "'"</span>
|
|
<span class="k">return</span> <span class="nx">readString</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">¶</a> </div> <p>Operators are parsed inline in tiny state machines. '=' (61) is
|
|
often referred to. <code>finishOp</code> simply skips the amount of
|
|
characters it is given as second argument, and returns a token
|
|
of the type given by its first argument.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">47</span><span class="o">:</span> <span class="c1">// '/'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_slash</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="mi">37</span><span class="o">:</span> <span class="k">case</span> <span class="mi">42</span><span class="o">:</span> <span class="c1">// '%*'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_mult_modulo</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">124</span><span class="o">:</span> <span class="k">case</span> <span class="mi">38</span><span class="o">:</span> <span class="c1">// '|&'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_pipe_amp</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">94</span><span class="o">:</span> <span class="c1">// '^'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_caret</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="mi">43</span><span class="o">:</span> <span class="k">case</span> <span class="mi">45</span><span class="o">:</span> <span class="c1">// '+-'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_plus_min</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">60</span><span class="o">:</span> <span class="k">case</span> <span class="mi">62</span><span class="o">:</span> <span class="c1">// '<>'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_lt_gt</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">61</span><span class="o">:</span> <span class="k">case</span> <span class="mi">33</span><span class="o">:</span> <span class="c1">// '=!'</span>
|
|
<span class="k">return</span> <span class="nx">readToken_eq_excl</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="mi">126</span><span class="o">:</span> <span class="c1">// '~'</span>
|
|
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_prefix</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readToken</span><span class="p">(</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="nx">tokStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">else</span> <span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">tokStart</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">tokStartLoc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readRegexp</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">>=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_eof</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">code</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">inTemplate</span><span class="p">)</span> <span class="k">return</span> <span class="nx">getTemplateToken</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">¶</a> </div> <p>Identifier or keyword. '\uXXXX' sequences are allowed in
|
|
identifiers, so '\' also dispatches to that.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">||</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">92</span> <span class="cm">/* '\' */</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readWord</span><span class="p">();</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">tok</span> <span class="o">=</span> <span class="nx">getTokenFromCode</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tok</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">¶</a> </div> <p>If we are here, we either found a non-ASCII identifier
|
|
character, or something that's entirely disallowed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">"\\"</span> <span class="o">||</span> <span class="nx">nonASCIIidentifierStart</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="k">return</span> <span class="nx">readWord</span><span class="p">();</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">"Unexpected character '"</span> <span class="o">+</span> <span class="nx">ch</span> <span class="o">+</span> <span class="s2">"'"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">tok</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">size</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+</span> <span class="nx">size</span><span class="p">);</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="nx">size</span><span class="p">;</span>
|
|
<span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">str</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">¶</a> </div> <p>Parse a regular expression. Some context-awareness is necessary,
|
|
since a '/' inside a '[]' set does not end the expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readRegexp</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span> <span class="nx">escaped</span><span class="p">,</span> <span class="nx">inClass</span><span class="p">,</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">>=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Unterminated regular expression"</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Unterminated regular expression"</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">escaped</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">"["</span><span class="p">)</span> <span class="nx">inClass</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">"]"</span> <span class="o">&&</span> <span class="nx">inClass</span><span class="p">)</span> <span class="nx">inClass</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">"/"</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">inClass</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="nx">escaped</span> <span class="o">=</span> <span class="nx">ch</span> <span class="o">===</span> <span class="s2">"\\"</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">escaped</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">¶</a> </div> <p>Need to use <code>readWord1</code> because '\uXXXX' sequences are allowed
|
|
here (don't ask).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">mods</span> <span class="o">=</span> <span class="nx">readWord1</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">mods</span> <span class="o">&&</span> <span class="o">!</span><span class="sr">/^[gmsiy]*$/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">mods</span><span class="p">))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Invalid regular expression flag"</span><span class="p">);</span>
|
|
<span class="k">try</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">content</span><span class="p">,</span> <span class="nx">mods</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">e</span> <span class="k">instanceof</span> <span class="nx">SyntaxError</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Error parsing regular expression: "</span> <span class="o">+</span> <span class="nx">e</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_regexp</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">¶</a> </div> <p>Read an integer in the given radix. Return null if zero digits
|
|
were read, the integer value otherwise. When <code>len</code> is given, this
|
|
will return <code>null</code> unless the integer has exactly <code>len</code> digits.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readInt</span><span class="p">(</span><span class="nx">radix</span><span class="p">,</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">,</span> <span class="nx">total</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">e</span> <span class="o">=</span> <span class="nx">len</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="kc">Infinity</span> <span class="o">:</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">e</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">code</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">),</span> <span class="nx">val</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">>=</span> <span class="mi">97</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">97</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// a</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">>=</span> <span class="mi">65</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">65</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// A</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">>=</span> <span class="mi">48</span> <span class="o">&&</span> <span class="nx">code</span> <span class="o"><=</span> <span class="mi">57</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">48</span><span class="p">;</span> <span class="c1">// 0-9</span>
|
|
<span class="k">else</span> <span class="nx">val</span> <span class="o">=</span> <span class="kc">Infinity</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o">>=</span> <span class="nx">radix</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="nx">total</span> <span class="o">=</span> <span class="nx">total</span> <span class="o">*</span> <span class="nx">radix</span> <span class="o">+</span> <span class="nx">val</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">===</span> <span class="nx">start</span> <span class="o">||</span> <span class="nx">len</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="nx">tokPos</span> <span class="o">-</span> <span class="nx">start</span> <span class="o">!==</span> <span class="nx">len</span><span class="p">)</span> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
|
|
|
|
<span class="k">return</span> <span class="nx">total</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readRadixNumber</span><span class="p">(</span><span class="nx">radix</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">// 0x</span>
|
|
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">readInt</span><span class="p">(</span><span class="nx">radix</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"Expected number in radix "</span> <span class="o">+</span> <span class="nx">radix</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">"Identifier directly after number"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_num</span><span class="p">,</span> <span class="nx">val</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">¶</a> </div> <p>Read an integer, octal integer, or floating-point number.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readNumber</span><span class="p">(</span><span class="nx">startsWithDot</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">,</span> <span class="nx">isFloat</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">octal</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="mi">48</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">startsWithDot</span> <span class="o">&&</span> <span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Invalid number"</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="mi">46</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
|
|
<span class="nx">isFloat</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">69</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">101</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 'eE'</span>
|
|
<span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">43</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">45</span><span class="p">)</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="c1">// '+-'</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Invalid number"</span><span class="p">);</span>
|
|
<span class="nx">isFloat</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">"Identifier directly after number"</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">),</span> <span class="nx">val</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isFloat</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">octal</span> <span class="o">||</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="sr">/[89]/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="o">||</span> <span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Invalid number"</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_num</span><span class="p">,</span> <span class="nx">val</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">¶</a> </div> <p>Read a string value, interpreting backslash-escapes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readCodePoint</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">),</span> <span class="nx">code</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">123</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o"><</span> <span class="mi">6</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="nx">code</span> <span class="o">=</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'}'</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">)</span> <span class="o">-</span> <span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">></span> <span class="mh">0x10FFFF</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">code</span> <span class="o">=</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-81">¶</a> </div> <p>UTF-16 Encoding</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o"><=</span> <span class="mh">0xFFFF</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">cu1</span> <span class="o">=</span> <span class="p">((</span><span class="nx">code</span> <span class="o">-</span> <span class="mh">0x10000</span><span class="p">)</span> <span class="o">>></span> <span class="mi">10</span><span class="p">)</span> <span class="o">+</span> <span class="mh">0xD800</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">cu2</span> <span class="o">=</span> <span class="p">((</span><span class="nx">code</span> <span class="o">-</span> <span class="mh">0x10000</span><span class="p">)</span> <span class="o">&</span> <span class="mi">1023</span><span class="p">)</span> <span class="o">+</span> <span class="mh">0xDC00</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">cu1</span><span class="p">,</span> <span class="nx">cu2</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readString</span><span class="p">(</span><span class="nx">quote</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">>=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"Unterminated string constant"</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="nx">quote</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_string</span><span class="p">,</span> <span class="nx">out</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">92</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '\'</span>
|
|
<span class="nx">out</span> <span class="o">+=</span> <span class="nx">readEscapedChar</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">)))</span> <span class="p">{</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"Unterminated string constant"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">out</span> <span class="o">+=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">);</span> <span class="c1">// '\'</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">readTmplString</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">out</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">>=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"Unterminated string constant"</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">96</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">36</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">===</span> <span class="mi">123</span><span class="p">)</span> <span class="c1">// '`', '${'</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_string</span><span class="p">,</span> <span class="nx">out</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">92</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// '\'</span>
|
|
<span class="nx">out</span> <span class="o">+=</span> <span class="nx">readEscapedChar</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">)))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">13</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="nx">ch</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">out</span> <span class="o">+=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">);</span> <span class="c1">// '\'</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-82">¶</a> </div> <p>Used to read escaped characters</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readEscapedChar</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">octal</span> <span class="o">=</span> <span class="sr">/^[0-7]+/</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">3</span><span class="p">));</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="nx">octal</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">octal</span> <span class="o">&&</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">octal</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">></span> <span class="mi">255</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="nx">octal</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span> <span class="o">===</span> <span class="s2">"0"</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"Octal literal in strict mode"</span><span class="p">);</span>
|
|
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="nx">octal</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">octal</span><span class="p">,</span> <span class="mi">8</span><span class="p">));</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">ch</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="mi">110</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\n"</span><span class="p">;</span> <span class="c1">// 'n' -> '\n'</span>
|
|
<span class="k">case</span> <span class="mi">114</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\r"</span><span class="p">;</span> <span class="c1">// 'r' -> '\r'</span>
|
|
<span class="k">case</span> <span class="mi">120</span><span class="o">:</span> <span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">readHexChar</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span> <span class="c1">// 'x'</span>
|
|
<span class="k">case</span> <span class="mi">117</span><span class="o">:</span> <span class="k">return</span> <span class="nx">readCodePoint</span><span class="p">();</span> <span class="c1">// 'u'</span>
|
|
<span class="k">case</span> <span class="mi">85</span><span class="o">:</span> <span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">readHexChar</span><span class="p">(</span><span class="mi">8</span><span class="p">));</span> <span class="c1">// 'U'</span>
|
|
<span class="k">case</span> <span class="mi">116</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\t"</span><span class="p">;</span> <span class="c1">// 't' -> '\t'</span>
|
|
<span class="k">case</span> <span class="mi">98</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\b"</span><span class="p">;</span> <span class="c1">// 'b' -> '\b'</span>
|
|
<span class="k">case</span> <span class="mi">118</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\u000b"</span><span class="p">;</span> <span class="c1">// 'v' -> '\u000b'</span>
|
|
<span class="k">case</span> <span class="mi">102</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\f"</span><span class="p">;</span> <span class="c1">// 'f' -> '\f'</span>
|
|
<span class="k">case</span> <span class="mi">48</span><span class="o">:</span> <span class="k">return</span> <span class="s2">"\0"</span><span class="p">;</span> <span class="c1">// 0 -> '\0'</span>
|
|
<span class="k">case</span> <span class="mi">13</span><span class="o">:</span> <span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="mi">10</span><span class="p">)</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="c1">// '\r\n'</span>
|
|
<span class="k">case</span> <span class="mi">10</span><span class="o">:</span> <span class="c1">// ' \n'</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span> <span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span> <span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span> <span class="p">}</span>
|
|
<span class="k">return</span> <span class="s2">""</span><span class="p">;</span>
|
|
<span class="k">default</span><span class="o">:</span> <span class="k">return</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-83">¶</a> </div> <p>Used to read character escape sequences ('\x', '\u', '\U').</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">n</span> <span class="o">=</span> <span class="nx">readInt</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="nx">len</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"Bad character escape sequence"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">n</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">¶</a> </div> <p>Used to signal to callers of <code>readWord1</code> whether the word
|
|
contained any escape sequences. This is needed because words with
|
|
escape sequences must not be interpreted as keywords.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">containsEsc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-85">¶</a> </div> <p>Read an identifier, and return it as a string. Sets <code>containsEsc</code>
|
|
to whether the word contained a '\u' escape.</p>
|
|
|
|
<p>Only builds up the word character-by-character when it actually
|
|
containeds an escape, as a micro-optimization.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readWord1</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">containsEsc</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">word</span><span class="p">,</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierChar</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">containsEsc</span><span class="p">)</span> <span class="nx">word</span> <span class="o">+=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">92</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// "\"</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">containsEsc</span><span class="p">)</span> <span class="nx">word</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="nx">containsEsc</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">117</span><span class="p">)</span> <span class="c1">// "u"</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">"Expecting Unicode escape sequence \\uXXXX"</span><span class="p">);</span>
|
|
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">esc</span> <span class="o">=</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">escStr</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">esc</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">escStr</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"Invalid Unicode escape"</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">first</span> <span class="o">?</span> <span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">esc</span><span class="p">)</span> <span class="o">:</span> <span class="nx">isIdentifierChar</span><span class="p">(</span><span class="nx">esc</span><span class="p">)))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">4</span><span class="p">,</span> <span class="s2">"Invalid Unicode escape"</span><span class="p">);</span>
|
|
<span class="nx">word</span> <span class="o">+=</span> <span class="nx">escStr</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">containsEsc</span> <span class="o">?</span> <span class="nx">word</span> <span class="o">:</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-86">¶</a> </div> <p>Read an identifier or keyword token. Will check for reserved
|
|
words when necessary.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readWord</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">word</span> <span class="o">=</span> <span class="nx">readWord1</span><span class="p">();</span>
|
|
<span class="kd">var</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">_name</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">containsEsc</span> <span class="o">&&</span> <span class="nx">isKeyword</span><span class="p">(</span><span class="nx">word</span><span class="p">))</span>
|
|
<span class="nx">type</span> <span class="o">=</span> <span class="nx">keywordTypes</span><span class="p">[</span><span class="nx">word</span><span class="p">];</span>
|
|
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">word</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-87">¶</a> </div> <h2>Parser</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">¶</a> </div> <p>A recursive descent parser operates by defining functions for all
|
|
syntactic elements, and recursively calling those, each function
|
|
advancing the input stream and returning an AST node. Precedence
|
|
of constructs (for example, the fact that <code>!x[1]</code> means <code>!(x[1])</code>
|
|
instead of <code>(!x)[1]</code> is handled by the fact that the parser
|
|
function that parses unary prefix operators is called first, and
|
|
in turn calls the function that parses <code>[]</code> subscripts — that
|
|
way, it'll receive the node for <code>x[1]</code> already parsed, and wraps
|
|
<em>that</em> in the unary operator node.</p>
|
|
|
|
<p>Acorn uses an <a href="http://en.wikipedia.org/wiki/Operator-precedence_parser">operator precedence parser</a> to handle binary
|
|
operator precedence, because it is much more compact than using
|
|
the technique outlined above, which uses different, nesting
|
|
functions to specify precedence, for all of the ten binary
|
|
precedence levels that JavaScript defines.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">¶</a> </div> <h3>Parser utilities</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-90">¶</a> </div> <p>Continue to the next token.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">next</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">lastStart</span> <span class="o">=</span> <span class="nx">tokStart</span><span class="p">;</span>
|
|
<span class="nx">lastEnd</span> <span class="o">=</span> <span class="nx">tokEnd</span><span class="p">;</span>
|
|
<span class="nx">lastEndLoc</span> <span class="o">=</span> <span class="nx">tokEndLoc</span><span class="p">;</span>
|
|
<span class="nx">readToken</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">¶</a> </div> <p>Enter strict mode. Re-reads the next token to please pedantic
|
|
tests ("use strict"; 010; -- should fail).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">setStrict</span><span class="p">(</span><span class="nx">strct</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">strict</span> <span class="o">=</span> <span class="nx">strct</span><span class="p">;</span>
|
|
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">tokStart</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o"><</span> <span class="nx">tokLineStart</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">lastIndexOf</span><span class="p">(</span><span class="s2">"\n"</span><span class="p">,</span> <span class="nx">tokLineStart</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
|
|
<span class="o">--</span><span class="nx">tokCurLine</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">skipSpace</span><span class="p">();</span>
|
|
<span class="nx">readToken</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">¶</a> </div> <p>Start an AST node, attaching a start offset.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">Node</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">tokStart</span><span class="p">;</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="nx">exports</span><span class="p">.</span><span class="nx">Node</span> <span class="o">=</span> <span class="nx">Node</span><span class="p">;</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">SourceLocation</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">tokStartLoc</span><span class="p">;</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">sourceFile</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">sourceFile</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">startNode</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Node</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SourceLocation</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">directSourceFile</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">sourceFile</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">directSourceFile</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="p">[</span><span class="nx">tokStart</span><span class="p">,</span> <span class="mi">0</span><span class="p">];</span>
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">¶</a> </div> <p>Start a node whose start offset information should be based on
|
|
the start of another node. For example, a binary operator node is
|
|
only started after its left-hand side has already been parsed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">other</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Node</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">other</span><span class="p">.</span><span class="nx">start</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SourceLocation</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">other</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">start</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="p">[</span><span class="nx">other</span><span class="p">.</span><span class="nx">range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">0</span><span class="p">];</span>
|
|
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-94">¶</a> </div> <p>Finish an AST node, adding <code>type</code> and <code>end</code> properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="nx">type</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEndLoc</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-95">¶</a> </div> <p>Test whether a statement node is the string literal <code>"use strict"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">5</span> <span class="o">&&</span> <span class="nx">stmt</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"ExpressionStatement"</span> <span class="o">&&</span>
|
|
<span class="nx">stmt</span><span class="p">.</span><span class="nx">expression</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Literal"</span> <span class="o">&&</span> <span class="nx">stmt</span><span class="p">.</span><span class="nx">expression</span><span class="p">.</span><span class="nx">value</span> <span class="o">===</span> <span class="s2">"use strict"</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-96">¶</a> </div> <p>Predicate that tests whether the next token is of the given
|
|
type, and if yes, consumes it as a side effect.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">¶</a> </div> <p>Test whether a semicolon can be inserted at the current position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">canInsertSemicolon</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">strictSemicolons</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_eof</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_braceR</span> <span class="o">||</span> <span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">tokStart</span><span class="p">)));</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">¶</a> </div> <p>Consume a semicolon, or, failing that, see if we are allowed to
|
|
pretend that there is a semicolon at this position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">semicolon</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-99">¶</a> </div> <p>Expect a token of a given type. If found, consume it, otherwise,
|
|
raise an unexpected token error.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">expect</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">eat</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">||</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-100">¶</a> </div> <p>Raise an unexpected token error.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">unexpected</span><span class="p">(</span><span class="nx">pos</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">pos</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">?</span> <span class="nx">pos</span> <span class="o">:</span> <span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"Unexpected token"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-101">¶</a> </div> <p>Checks if hash object has a property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">propName</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">propName</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-102">¶</a> </div> <p>Convert existing expression atom to assignable pattern
|
|
if possible.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">allowSpread</span><span class="p">,</span> <span class="nx">checkType</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="s2">"Identifier"</span><span class="o">:</span>
|
|
<span class="k">case</span> <span class="s2">"MemberExpression"</span><span class="o">:</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ObjectExpression"</span><span class="o">:</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="s2">"ObjectPattern"</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">prop</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">!==</span> <span class="s2">"init"</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">start</span><span class="p">);</span>
|
|
<span class="nx">toAssignable</span><span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">checkType</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ArrayExpression"</span><span class="o">:</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="s2">"ArrayPattern"</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">lastI</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">elements</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><=</span> <span class="nx">lastI</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">toAssignable</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">elements</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">i</span> <span class="o">===</span> <span class="nx">lastI</span><span class="p">,</span> <span class="nx">checkType</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"SpreadElement"</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">allowSpread</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">toAssignable</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">checkType</span><span class="p">);</span>
|
|
<span class="nx">checkSpreadAssign</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">unexpected</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">default</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">checkType</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-103">¶</a> </div> <p>Checks if node can be assignable spread argument.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">checkSpreadAssign</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">!==</span> <span class="s2">"Identifier"</span> <span class="o">&&</span> <span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">!==</span> <span class="s2">"ArrayPattern"</span><span class="p">)</span>
|
|
<span class="nx">unexpected</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-104">¶</a> </div> <p>Verify that argument names are not repeated, and it does not
|
|
try to bind the words <code>eval</code> or <code>arguments</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">param</span><span class="p">,</span> <span class="nx">nameHash</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="s2">"Identifier"</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isStrictReservedWord</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">||</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Defining '"</span> <span class="o">+</span> <span class="nx">param</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">"' in strict mode"</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">has</span><span class="p">(</span><span class="nx">nameHash</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Argument name clash in strict mode"</span><span class="p">);</span>
|
|
<span class="nx">nameHash</span><span class="p">[</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ObjectPattern"</span><span class="o">:</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">param</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span>
|
|
<span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">value</span><span class="p">,</span> <span class="nx">nameHash</span><span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ArrayPattern"</span><span class="o">:</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">param</span><span class="p">.</span><span class="nx">elements</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span>
|
|
<span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">elements</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">nameHash</span><span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-105">¶</a> </div> <p>Check if property name clashes with already added.
|
|
Object/class getters and setters are not allowed to clash —
|
|
either with each other or with an init property — and in
|
|
strict mode, init properties are also not allowed to be repeated.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">checkPropClash</span><span class="p">(</span><span class="nx">prop</span><span class="p">,</span> <span class="nx">propHash</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">computed</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">,</span> <span class="nx">name</span><span class="p">;</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="s2">"Identifier"</span><span class="o">:</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">key</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="k">case</span> <span class="s2">"Literal"</span><span class="o">:</span> <span class="nx">name</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="k">default</span><span class="o">:</span> <span class="k">return</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">kind</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">||</span> <span class="s2">"init"</span><span class="p">,</span> <span class="nx">other</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">has</span><span class="p">(</span><span class="nx">propHash</span><span class="p">,</span> <span class="nx">name</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">other</span> <span class="o">=</span> <span class="nx">propHash</span><span class="p">[</span><span class="nx">name</span><span class="p">];</span>
|
|
<span class="kd">var</span> <span class="nx">isGetSet</span> <span class="o">=</span> <span class="nx">kind</span> <span class="o">!==</span> <span class="s2">"init"</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">((</span><span class="nx">strict</span> <span class="o">||</span> <span class="nx">isGetSet</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">other</span><span class="p">[</span><span class="nx">kind</span><span class="p">]</span> <span class="o">||</span> <span class="o">!</span><span class="p">(</span><span class="nx">isGetSet</span> <span class="o">^</span> <span class="nx">other</span><span class="p">.</span><span class="nx">init</span><span class="p">))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Redefinition of property"</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">other</span> <span class="o">=</span> <span class="nx">propHash</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="nx">init</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">get</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">set</span><span class="o">:</span> <span class="kc">false</span>
|
|
<span class="p">};</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">other</span><span class="p">[</span><span class="nx">kind</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-106">¶</a> </div> <p>Verify that a node is an lval — something that can be assigned
|
|
to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">checkLVal</span><span class="p">(</span><span class="nx">expr</span><span class="p">,</span> <span class="nx">isBinding</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="s2">"Identifier"</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&&</span> <span class="p">(</span><span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">||</span> <span class="nx">isStrictReservedWord</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">name</span><span class="p">)))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="nx">isBinding</span>
|
|
<span class="o">?</span> <span class="s2">"Binding "</span> <span class="o">+</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">" in strict mode"</span>
|
|
<span class="o">:</span> <span class="s2">"Assigning to "</span> <span class="o">+</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">" in strict mode"</span>
|
|
<span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"MemberExpression"</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">isBinding</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ObjectPattern"</span><span class="o">:</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">value</span><span class="p">,</span> <span class="nx">isBinding</span><span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"ArrayPattern"</span><span class="o">:</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">elements</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">elements</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">elem</span><span class="p">)</span> <span class="nx">checkLVal</span><span class="p">(</span><span class="nx">elem</span><span class="p">,</span> <span class="nx">isBinding</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="s2">"SpreadElement"</span><span class="o">:</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
|
|
<span class="k">default</span><span class="o">:</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Assigning to rvalue"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-107">¶</a> </div> <h3>Statement parsing</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-108">¶</a> </div> <p>Parse a program. Initializes the parser, reads any number of
|
|
statements, and wraps them in a Program node. Optionally takes a
|
|
<code>program</code> argument. If present, the statements will be appended
|
|
to its body instead of creating a new node.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseTopLevel</span><span class="p">(</span><span class="nx">program</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">lastStart</span> <span class="o">=</span> <span class="nx">lastEnd</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">lastEndLoc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Position</span><span class="p">;</span>
|
|
<span class="nx">inFunction</span> <span class="o">=</span> <span class="nx">inGenerator</span> <span class="o">=</span> <span class="nx">strict</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">labels</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">readToken</span><span class="p">();</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">program</span> <span class="o">||</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">program</span><span class="p">)</span> <span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_eof</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">stmt</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">stmt</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">first</span> <span class="o">&&</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">))</span> <span class="nx">setStrict</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"Program"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">loopLabel</span> <span class="o">=</span> <span class="p">{</span><span class="nx">kind</span><span class="o">:</span> <span class="s2">"loop"</span><span class="p">},</span> <span class="nx">switchLabel</span> <span class="o">=</span> <span class="p">{</span><span class="nx">kind</span><span class="o">:</span> <span class="s2">"switch"</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-109">¶</a> </div> <p>Parse a single statement.</p>
|
|
|
|
<p>If expecting a statement and finding a slash operator, parse a
|
|
regular expression literal. This is to handle cases like
|
|
<code>if (foo) /blah/.exec(foo);</code>, where looking at the previous token
|
|
does not help.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseStatement</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_slash</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_assign</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">==</span> <span class="s2">"/="</span><span class="p">)</span>
|
|
<span class="nx">readToken</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">starttype</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">,</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-110">¶</a> </div> <p>Most types of statements are recognized by the keyword they
|
|
start with. Many are trivial to parse, some require a bit of
|
|
complexity.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">switch</span> <span class="p">(</span><span class="nx">starttype</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="nx">_break</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_continue</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseBreakContinueStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">starttype</span><span class="p">.</span><span class="nx">keyword</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_debugger</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseDebuggerStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_do</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseDoStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_for</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseForStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_function</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseFunctionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_class</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseClass</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_if</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseIfStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_return</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseReturnStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_switch</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseSwitchStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_throw</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseThrowStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_try</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseTryStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_var</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_let</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_const</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseVarStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">starttype</span><span class="p">.</span><span class="nx">keyword</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_while</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseWhileStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_with</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseWithStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_braceL</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseBlock</span><span class="p">();</span> <span class="c1">// no point creating a function for this</span>
|
|
<span class="k">case</span> <span class="nx">_semi</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseEmptyStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_export</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseExport</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">case</span> <span class="nx">_import</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseImport</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-111">¶</a> </div> <p>If the statement does not start with a statement keyword or a
|
|
brace, it's an ExpressionStatement or LabeledStatement. We
|
|
simply start parsing an expression, and afterwards, if the
|
|
next token is a colon and the expression was a simple
|
|
Identifier node, we switch to interpreting it as a label.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">default</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">maybeName</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">,</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">starttype</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="nx">parseLabeledStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">expr</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="k">return</span> <span class="nx">parseExpressionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">expr</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseBreakContinueStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">keyword</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">isBreak</span> <span class="o">=</span> <span class="nx">keyword</span> <span class="o">==</span> <span class="s2">"break"</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">||</span> <span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-112">¶</a> </div> <p>Verify that there is an actual destination to break or
|
|
continue to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">lab</span> <span class="o">=</span> <span class="nx">labels</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="nx">lab</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">node</span><span class="p">.</span><span class="nx">label</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">lab</span><span class="p">.</span><span class="nx">kind</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="p">(</span><span class="nx">isBreak</span> <span class="o">||</span> <span class="nx">lab</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">"loop"</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">&&</span> <span class="nx">isBreak</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">===</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Unsyntactic "</span> <span class="o">+</span> <span class="nx">keyword</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isBreak</span> <span class="o">?</span> <span class="s2">"BreakStatement"</span> <span class="o">:</span> <span class="s2">"ContinueStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseDebuggerStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"DebuggerStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseDoStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_while</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"DoWhileStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-113">¶</a> </div> <p>Disambiguating between a <code>for</code> and a <code>for</code>/<code>in</code> or <code>for</code>/<code>of</code>
|
|
loop is non-trivial. Basically, we have to parse the init <code>var</code>
|
|
statement or expression, disallowing the <code>in</code> operator (see
|
|
the second parameter to <code>parseExpression</code>), and then check
|
|
whether the next token is <code>in</code> or <code>of</code>. When there is no init
|
|
part (semicolon immediately after the opening parenthesis), it
|
|
is a regular <code>for</code> loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseForStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_semi</span><span class="p">)</span> <span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">null</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_var</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_let</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">init</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">varKind</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">,</span> <span class="nx">isLet</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_let</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">parseVar</span><span class="p">(</span><span class="nx">init</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">varKind</span><span class="p">);</span>
|
|
<span class="nx">finishNode</span><span class="p">(</span><span class="nx">init</span><span class="p">,</span> <span class="s2">"VariableDeclaration"</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">((</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_in</span> <span class="o">||</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"of"</span><span class="p">))</span> <span class="o">&&</span> <span class="nx">init</span><span class="p">.</span><span class="nx">declarations</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">&&</span>
|
|
<span class="o">!</span><span class="p">(</span><span class="nx">isLet</span> <span class="o">&&</span> <span class="nx">init</span><span class="p">.</span><span class="nx">declarations</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">init</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">init</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_in</span> <span class="o">||</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"of"</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">init</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseFunctionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseIfStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">alternate</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_else</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseStatement</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"IfStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseReturnStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">inFunction</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowReturnOutsideFunction</span><span class="p">)</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"'return' outside of function"</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-114">¶</a> </div> <p>In <code>return</code> (and <code>break</code>/<code>continue</code>), the keywords with
|
|
optional arguments, we eagerly look for a semicolon or the
|
|
possibility to insert one.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">||</span> <span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">else</span> <span class="p">{</span> <span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span> <span class="nx">semicolon</span><span class="p">();</span> <span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ReturnStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseSwitchStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">discriminant</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">cases</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">switchLabel</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-115">¶</a> </div> <p>Statements under must be grouped (by label) in SwitchCase
|
|
nodes. <code>cur</code> is used to keep the node that we are currently
|
|
adding statements to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">cur</span><span class="p">,</span> <span class="nx">sawDefault</span><span class="p">;</span> <span class="nx">tokType</span> <span class="o">!=</span> <span class="nx">_braceR</span><span class="p">;)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_case</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_default</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">isCase</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_case</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">cur</span><span class="p">,</span> <span class="s2">"SwitchCase"</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">cases</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">cur</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">());</span>
|
|
<span class="nx">cur</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isCase</span><span class="p">)</span> <span class="nx">cur</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">sawDefault</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">lastStart</span><span class="p">,</span> <span class="s2">"Multiple default clauses"</span><span class="p">);</span> <span class="nx">sawDefault</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">cur</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">cur</span><span class="p">.</span><span class="nx">consequent</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseStatement</span><span class="p">());</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">cur</span><span class="p">,</span> <span class="s2">"SwitchCase"</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span> <span class="c1">// Closing brace</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"SwitchStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseThrowStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">tokStart</span><span class="p">)))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="s2">"Illegal newline after throw"</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ThrowStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseTryStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">block</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">handler</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_catch</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">clause</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="nx">clause</span><span class="p">.</span><span class="nx">param</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&&</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Binding "</span> <span class="o">+</span> <span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">" in strict mode"</span><span class="p">);</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="nx">clause</span><span class="p">.</span><span class="nx">guard</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">clause</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">handler</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">clause</span><span class="p">,</span> <span class="s2">"CatchClause"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">guardedHandlers</span> <span class="o">=</span> <span class="nx">empty</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">finalizer</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_finally</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseBlock</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">handler</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">finalizer</span><span class="p">)</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Missing catch or finally clause"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"TryStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseVarStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">kind</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">parseVar</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">kind</span><span class="p">);</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"VariableDeclaration"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseWhileStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"WhileStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseWithStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"'with' in strict mode"</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"WithStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseEmptyStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"EmptyStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseLabeledStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">expr</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">labels</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">maybeName</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Label '"</span> <span class="o">+</span> <span class="nx">maybeName</span> <span class="o">+</span> <span class="s2">"' is already declared"</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">kind</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">isLoop</span> <span class="o">?</span> <span class="s2">"loop"</span> <span class="o">:</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_switch</span> <span class="o">?</span> <span class="s2">"switch"</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">kind</span><span class="o">:</span> <span class="nx">kind</span><span class="p">});</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"LabeledStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseExpressionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">expr</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expression</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ExpressionStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-116">¶</a> </div> <p>Used for constructs like <code>switch</code> and <code>if</code> that insist on
|
|
parentheses around their expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseParenExpression</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-117">¶</a> </div> <p>Parse a semicolon-enclosed block of statements, handling <code>"use
|
|
strict"</code> declarations when <code>allowStrict</code> is true (used for
|
|
function bodies).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseBlock</span><span class="p">(</span><span class="nx">allowStrict</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">strict</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">oldStrict</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">stmt</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">stmt</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">first</span> <span class="o">&&</span> <span class="nx">allowStrict</span> <span class="o">&&</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">oldStrict</span> <span class="o">=</span> <span class="nx">strict</span><span class="p">;</span>
|
|
<span class="nx">setStrict</span><span class="p">(</span><span class="nx">strict</span> <span class="o">=</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">oldStrict</span><span class="p">)</span> <span class="nx">setStrict</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"BlockStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">¶</a> </div> <p>Parse a regular <code>for</code> loop. The disambiguation code in
|
|
<code>parseStatement</code> will already have parsed the init statement or
|
|
expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="nx">init</span><span class="p">;</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_semi</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">update</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_parenR</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ForStatement"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">¶</a> </div> <p>Parse a <code>for</code>/<code>in</code> and <code>for</code>/<code>of</code> loop, which are almost
|
|
same from parser's perspective.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_in</span> <span class="o">?</span> <span class="s2">"ForInStatement"</span> <span class="o">:</span> <span class="s2">"ForOfStatement"</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">init</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">type</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-120">¶</a> </div> <p>Parse a list of variable declarations.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseVar</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">,</span> <span class="nx">kind</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">declarations</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="nx">kind</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">decl</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">decl</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">?</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">())</span> <span class="o">:</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">decl</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">decl</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_eq</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="o">:</span> <span class="p">(</span><span class="nx">kind</span> <span class="o">===</span> <span class="nx">_const</span><span class="p">.</span><span class="nx">keyword</span> <span class="o">?</span> <span class="nx">unexpected</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">declarations</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">decl</span><span class="p">,</span> <span class="s2">"VariableDeclarator"</span><span class="p">));</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-121">¶</a> </div> <h3>Expression parsing</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-122">¶</a> </div> <p>These nest, from the most general expression type at the top to
|
|
'atomic', nondivisible expression types at the bottom. Most of
|
|
the functions will simply let the function(s) below them parse,
|
|
and, <em>if</em> the syntactic construct they handle is present, wrap
|
|
the AST node that the inner parser gave them in another node.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-123">¶</a> </div> <p>Parse a full expression. The arguments are used to forbid comma
|
|
sequences (in argument lists, array literals, or object literals)
|
|
or the <code>in</code> operator (in for loops initalization expressions).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="nx">noComma</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">noComma</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_comma</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="nx">expr</span><span class="p">];</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">));</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"SequenceExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-124">¶</a> </div> <p>Parse an assignment expression. This includes applications of
|
|
operators like <code>+=</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">left</span> <span class="o">=</span> <span class="nx">parseMaybeConditional</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">isAssign</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_eq</span> <span class="o">?</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">left</span><span class="p">)</span> <span class="o">:</span> <span class="nx">left</span><span class="p">;</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"AssignmentExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">left</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-125">¶</a> </div> <p>Parse a ternary conditional (<code>?:</code>) operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeConditional</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExprOps</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_question</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">alternate</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ConditionalExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-126">¶</a> </div> <p>Start the precedence parser.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprOps</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">parseMaybeUnary</span><span class="p">(),</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">¶</a> </div> <p>Parse binary operators with the operator precedence parsing
|
|
algorithm. <code>left</code> is the left-hand side of the operator.
|
|
<code>minPrec</code> provides context that allows the function to stop and
|
|
defer further parser to one of its callers when it encounters an
|
|
operator that has a lower precedence than the set it is parsing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">left</span><span class="p">,</span> <span class="nx">minPrec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">prec</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">binop</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">prec</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="p">(</span><span class="o">!</span><span class="nx">noIn</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_in</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">prec</span> <span class="o">></span> <span class="nx">minPrec</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">left</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">op</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">parseMaybeUnary</span><span class="p">(),</span> <span class="nx">prec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">exprNode</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="p">(</span><span class="nx">op</span> <span class="o">===</span> <span class="nx">_logicalOR</span> <span class="o">||</span> <span class="nx">op</span> <span class="o">===</span> <span class="nx">_logicalAND</span><span class="p">)</span> <span class="o">?</span> <span class="s2">"LogicalExpression"</span> <span class="o">:</span> <span class="s2">"BinaryExpression"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">exprNode</span><span class="p">,</span> <span class="nx">minPrec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">left</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">¶</a> </div> <p>Parse unary operators, both prefix and postfix.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeUnary</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">prefix</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">update</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">isUpdate</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseMaybeUnary</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">update</span><span class="p">)</span> <span class="nx">checkLVal</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&&</span> <span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">===</span> <span class="s2">"delete"</span> <span class="o">&&</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span><span class="p">)</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">"Deleting local variable in strict mode"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">update</span> <span class="o">?</span> <span class="s2">"UpdateExpression"</span> <span class="o">:</span> <span class="s2">"UnaryExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExprSubscripts</span><span class="p">();</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">postfix</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">prefix</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">expr</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"UpdateExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">¶</a> </div> <p>Parse call, dot, and <code>[]</code>-subscript expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprSubscripts</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">());</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">base</span><span class="p">,</span> <span class="nx">noCalls</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_dot</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">property</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"MemberExpression"</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_bracketL</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">property</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"MemberExpression"</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">noCalls</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">callee</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"CallExpression"</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_bquote</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">tag</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">quasi</span> <span class="o">=</span> <span class="nx">parseTemplate</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"TaggedTemplateExpression"</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">return</span> <span class="nx">base</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">¶</a> </div> <p>Parse an atomic expression — either a single token that is an
|
|
expression, an expression started by a keyword like <code>function</code> or
|
|
<code>new</code>, or an expression wrapped in punctuation like <code>()</code>, <code>[]</code>,
|
|
or <code>{}</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprAtom</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">switch</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="nx">_this</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ThisExpression"</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_yield</span><span class="o">:</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">inGenerator</span><span class="p">)</span> <span class="k">return</span> <span class="nx">parseYield</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_name</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_arrow</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nx">parseArrowExpression</span><span class="p">(</span><span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">id</span><span class="p">),</span> <span class="p">[</span><span class="nx">id</span><span class="p">]);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">id</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_num</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_string</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_regexp</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">raw</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="nx">tokEnd</span><span class="p">);</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"Literal"</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_null</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_true</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_false</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">atomValue</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">raw</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"Literal"</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_parenL</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">tokStartLoc1</span> <span class="o">=</span> <span class="nx">tokStartLoc</span><span class="p">,</span> <span class="nx">tokStart1</span> <span class="o">=</span> <span class="nx">tokStart</span><span class="p">,</span> <span class="nx">val</span><span class="p">,</span> <span class="nx">exprList</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">¶</a> </div> <p>check whether this is generator comprehension or regular expression</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_for</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">val</span> <span class="o">=</span> <span class="nx">parseComprehension</span><span class="p">(</span><span class="nx">startNode</span><span class="p">(),</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">oldParenL</span> <span class="o">=</span> <span class="o">++</span><span class="nx">metParenL</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_parenR</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">val</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">exprList</span> <span class="o">=</span> <span class="nx">val</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"SequenceExpression"</span> <span class="o">?</span> <span class="nx">val</span><span class="p">.</span><span class="nx">expressions</span> <span class="o">:</span> <span class="p">[</span><span class="nx">val</span><span class="p">];</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">exprList</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">¶</a> </div> <p>if '=>' follows '(...)', convert contents to arguments</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">metParenL</span> <span class="o">===</span> <span class="nx">oldParenL</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_arrow</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">val</span> <span class="o">=</span> <span class="nx">parseArrowExpression</span><span class="p">(</span><span class="nx">startNode</span><span class="p">(),</span> <span class="nx">exprList</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">¶</a> </div> <p>forbid '()' before everything but '=>'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">val</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">(</span><span class="nx">lastStart</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">¶</a> </div> <p>forbid '...' in sequence expressions</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">exprList</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">exprList</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"SpreadElement"</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">val</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">tokStart1</span><span class="p">;</span>
|
|
<span class="nx">val</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">val</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">start</span> <span class="o">=</span> <span class="nx">tokStartLoc1</span><span class="p">;</span>
|
|
<span class="nx">val</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEndLoc</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">val</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="p">[</span><span class="nx">tokStart1</span><span class="p">,</span> <span class="nx">lastEnd</span><span class="p">];</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_bracketL</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">¶</a> </div> <p>check whether this is array comprehension or regular array</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_for</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="nx">parseComprehension</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">elements</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ArrayExpression"</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_braceL</span><span class="o">:</span>
|
|
<span class="k">return</span> <span class="nx">parseObj</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_function</span><span class="o">:</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_class</span><span class="o">:</span>
|
|
<span class="k">return</span> <span class="nx">parseClass</span><span class="p">(</span><span class="nx">startNode</span><span class="p">(),</span> <span class="kc">false</span><span class="p">);</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_new</span><span class="o">:</span>
|
|
<span class="k">return</span> <span class="nx">parseNew</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_ellipsis</span><span class="o">:</span>
|
|
<span class="k">return</span> <span class="nx">parseSpread</span><span class="p">();</span>
|
|
|
|
<span class="k">case</span> <span class="nx">_bquote</span><span class="o">:</span>
|
|
<span class="k">return</span> <span class="nx">parseTemplate</span><span class="p">();</span>
|
|
|
|
<span class="k">default</span><span class="o">:</span>
|
|
<span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">¶</a> </div> <p>New's precedence is slightly tricky. It must allow its argument
|
|
to be a <code>[]</code> or dot subscript expression, but not a call — at
|
|
least, not without wrapping it in parentheses. Thus, it uses the</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseNew</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">callee</span> <span class="o">=</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">(),</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">))</span> <span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="nx">empty</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"NewExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">¶</a> </div> <p>Parse spread element '...expr'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseSpread</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"SpreadElement"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">¶</a> </div> <p>Parse template expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseTemplate</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">quasis</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">inTemplate</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">elem</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">elem</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="p">{</span><span class="nx">cooked</span><span class="o">:</span> <span class="nx">tokVal</span><span class="p">,</span> <span class="nx">raw</span><span class="o">:</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="nx">tokEnd</span><span class="p">)};</span>
|
|
<span class="nx">elem</span><span class="p">.</span><span class="nx">tail</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">quasis</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">elem</span><span class="p">,</span> <span class="s2">"TemplateElement"</span><span class="p">));</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_bquote</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// '`', end of template</span>
|
|
<span class="nx">elem</span><span class="p">.</span><span class="nx">tail</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">inTemplate</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_dollarBraceL</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseExpression</span><span class="p">());</span>
|
|
<span class="nx">inTemplate</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">inTemplate</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"TemplateLiteral"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">¶</a> </div> <p>Parse an object literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseObj</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">propHash</span> <span class="o">=</span> <span class="p">{};</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">properties</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">prop</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">isGenerator</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">method</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">shorthand</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">isGenerator</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_star</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">parsePropertyName</span><span class="p">(</span><span class="nx">prop</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">"init"</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_parenL</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">"init"</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">method</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseMethod</span><span class="p">(</span><span class="nx">isGenerator</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">5</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">prop</span><span class="p">.</span><span class="nx">computed</span> <span class="o">&&</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">"get"</span> <span class="o">||</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">"set"</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isGenerator</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span>
|
|
<span class="nx">parsePropertyName</span><span class="p">(</span><span class="nx">prop</span><span class="p">);</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseMethod</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">prop</span><span class="p">.</span><span class="nx">computed</span> <span class="o">&&</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">"init"</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">shorthand</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
|
|
<span class="nx">checkPropClash</span><span class="p">(</span><span class="nx">prop</span><span class="p">,</span> <span class="nx">propHash</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">prop</span><span class="p">,</span> <span class="s2">"Property"</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ObjectExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">function</span> <span class="nx">parsePropertyName</span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_bracketL</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">key</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">);</span>
|
|
<span class="k">return</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">prop</span><span class="p">.</span><span class="nx">key</span> <span class="o">=</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_num</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseExprAtom</span><span class="p">()</span> <span class="o">:</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">¶</a> </div> <p>Initialize empty function node.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">initFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">params</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">defaults</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">rest</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">generator</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">¶</a> </div> <p>Parse a function declaration or literal (depending on the
|
|
<code>isStatement</code> parameter).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span><span class="p">,</span> <span class="nx">allowExpressionBody</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">initFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">generator</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_star</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isStatement</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">parseFunctionParams</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="nx">parseFunctionBody</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">allowExpressionBody</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span> <span class="o">?</span> <span class="s2">"FunctionDeclaration"</span> <span class="o">:</span> <span class="s2">"FunctionExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">¶</a> </div> <p>Parse object or class method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMethod</span><span class="p">(</span><span class="nx">isGenerator</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">initFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="nx">parseFunctionParams</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
<span class="kd">var</span> <span class="nx">allowExpressionBody</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">generator</span> <span class="o">=</span> <span class="nx">isGenerator</span><span class="p">;</span>
|
|
<span class="nx">allowExpressionBody</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">allowExpressionBody</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">parseFunctionBody</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">allowExpressionBody</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"FunctionExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">¶</a> </div> <p>Parse arrow function expression with given parameters.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseArrowExpression</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">initFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">defaults</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">defaults</span><span class="p">,</span> <span class="nx">hasDefaults</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">lastI</span> <span class="o">=</span> <span class="nx">params</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><=</span> <span class="nx">lastI</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">param</span> <span class="o">=</span> <span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"AssignmentExpression"</span> <span class="o">&&</span> <span class="nx">param</span><span class="p">.</span><span class="nx">operator</span> <span class="o">===</span> <span class="s2">"="</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">hasDefaults</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">param</span><span class="p">.</span><span class="nx">left</span><span class="p">;</span>
|
|
<span class="nx">defaults</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">right</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">toAssignable</span><span class="p">(</span><span class="nx">param</span><span class="p">,</span> <span class="nx">i</span> <span class="o">===</span> <span class="nx">lastI</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">defaults</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"SpreadElement"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">params</span><span class="p">.</span><span class="nx">length</span><span class="o">--</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">rest</span> <span class="o">=</span> <span class="nx">param</span><span class="p">.</span><span class="nx">argument</span><span class="p">;</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">params</span> <span class="o">=</span> <span class="nx">params</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">hasDefaults</span><span class="p">)</span> <span class="nx">node</span><span class="p">.</span><span class="nx">defaults</span> <span class="o">=</span> <span class="p">[];</span>
|
|
|
|
<span class="nx">parseFunctionBody</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ArrowFunctionExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-144">¶</a> </div> <p>Parse function parameters.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFunctionParams</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">defaults</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">hasDefaults</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_ellipsis</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">rest</span> <span class="o">=</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">(),</span> <span class="kc">false</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">checkSpreadAssign</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">rest</span><span class="p">);</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">?</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">(),</span> <span class="kc">false</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span> <span class="o">:</span> <span class="nx">parseIdent</span><span class="p">());</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">>=</span> <span class="mi">6</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_eq</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">hasDefaults</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">defaults</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">hasDefaults</span><span class="p">)</span> <span class="nx">node</span><span class="p">.</span><span class="nx">defaults</span> <span class="o">=</span> <span class="nx">defaults</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">¶</a> </div> <p>Parse function body and check parameters.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFunctionBody</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">allowExpression</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">isExpression</span> <span class="o">=</span> <span class="nx">allowExpression</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_braceL</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isExpression</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expression</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-146">¶</a> </div> <p>Start a new scope with regard to labels and the <code>inFunction</code>
|
|
flag (restore them to their old value afterwards).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">oldInFunc</span> <span class="o">=</span> <span class="nx">inFunction</span><span class="p">,</span> <span class="nx">oldInGen</span> <span class="o">=</span> <span class="nx">inGenerator</span><span class="p">,</span> <span class="nx">oldLabels</span> <span class="o">=</span> <span class="nx">labels</span><span class="p">;</span>
|
|
<span class="nx">inFunction</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> <span class="nx">inGenerator</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">generator</span><span class="p">;</span> <span class="nx">labels</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">expression</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">inFunction</span> <span class="o">=</span> <span class="nx">oldInFunc</span><span class="p">;</span> <span class="nx">inGenerator</span> <span class="o">=</span> <span class="nx">oldInGen</span><span class="p">;</span> <span class="nx">labels</span> <span class="o">=</span> <span class="nx">oldLabels</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-147">¶</a> </div> <p>If this is a strict mode function, verify that argument names
|
|
are not repeated, and it does not try to bind the words <code>eval</code>
|
|
or <code>arguments</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">||</span> <span class="o">!</span><span class="nx">isExpression</span> <span class="o">&&</span> <span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">length</span> <span class="o">&&</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">nameHash</span> <span class="o">=</span> <span class="p">{};</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span>
|
|
<span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span>
|
|
<span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">nameHash</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">rest</span><span class="p">)</span>
|
|
<span class="nx">checkFunctionParam</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">rest</span><span class="p">,</span> <span class="nx">nameHash</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-148">¶</a> </div> <p>Parse a class declaration or literal (depending on the
|
|
<code>isStatement</code> parameter).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseClass</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">?</span> <span class="nx">parseIdent</span><span class="p">()</span> <span class="o">:</span> <span class="nx">isStatement</span> <span class="o">?</span> <span class="nx">unexpected</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">superClass</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_extends</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseExpression</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="kd">var</span> <span class="nx">classBody</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">methodHash</span> <span class="o">=</span> <span class="p">{},</span> <span class="nx">staticMethodHash</span> <span class="o">=</span> <span class="p">{};</span>
|
|
<span class="nx">classBody</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">method</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"static"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">method</span><span class="p">[</span><span class="s1">'static'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">method</span><span class="p">[</span><span class="s1">'static'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="kd">var</span> <span class="nx">isGenerator</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_star</span><span class="p">);</span>
|
|
<span class="nx">parsePropertyName</span><span class="p">(</span><span class="nx">method</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">method</span><span class="p">.</span><span class="nx">computed</span> <span class="o">&&</span> <span class="nx">method</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="nx">method</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">"get"</span> <span class="o">||</span> <span class="nx">method</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">"set"</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isGenerator</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">method</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="nx">method</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span>
|
|
<span class="nx">parsePropertyName</span><span class="p">(</span><span class="nx">method</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">method</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">method</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseMethod</span><span class="p">(</span><span class="nx">isGenerator</span><span class="p">);</span>
|
|
<span class="nx">checkPropClash</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="nx">method</span><span class="p">[</span><span class="s1">'static'</span><span class="p">]</span> <span class="o">?</span> <span class="nx">staticMethodHash</span> <span class="o">:</span> <span class="nx">methodHash</span><span class="p">);</span>
|
|
<span class="nx">classBody</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="s2">"MethodDefinition"</span><span class="p">));</span>
|
|
<span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">classBody</span><span class="p">,</span> <span class="s2">"ClassBody"</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span> <span class="o">?</span> <span class="s2">"ClassDeclaration"</span> <span class="o">:</span> <span class="s2">"ClassExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-149">¶</a> </div> <p>Parses a comma-separated list of expressions, and returns them as
|
|
an array. <code>close</code> is the token type that ends the list, and
|
|
<code>allowEmpty</code> can be turned on to allow subsequent commas with
|
|
nothing in between them to be parsed as <code>null</code> (which is needed
|
|
for array literals).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">close</span><span class="p">,</span> <span class="nx">allowTrailingComma</span><span class="p">,</span> <span class="nx">allowEmpty</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">elts</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">close</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">allowTrailingComma</span> <span class="o">&&</span> <span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">close</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">allowEmpty</span> <span class="o">&&</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_comma</span><span class="p">)</span> <span class="nx">elts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
|
|
<span class="k">else</span> <span class="nx">elts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">elts</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-150">¶</a> </div> <p>Parse the next token as an identifier. If <code>liberal</code> is true (used
|
|
when parsing properties), it will also convert keywords into
|
|
identifiers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="nx">liberal</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">liberal</span> <span class="o">&&</span> <span class="nx">options</span><span class="p">.</span><span class="nx">forbidReserved</span> <span class="o">==</span> <span class="s2">"everywhere"</span><span class="p">)</span> <span class="nx">liberal</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">liberal</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">forbidReserved</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">===</span> <span class="mi">3</span> <span class="o">?</span> <span class="nx">isReservedWord3</span> <span class="o">:</span> <span class="nx">isReservedWord5</span><span class="p">)(</span><span class="nx">tokVal</span><span class="p">)</span> <span class="o">||</span>
|
|
<span class="nx">strict</span> <span class="o">&&</span> <span class="nx">isStrictReservedWord</span><span class="p">(</span><span class="nx">tokVal</span><span class="p">))</span> <span class="o">&&</span>
|
|
<span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="nx">tokEnd</span><span class="p">).</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">"\\"</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">"The keyword '"</span> <span class="o">+</span> <span class="nx">tokVal</span> <span class="o">+</span> <span class="s2">"' is reserved"</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">liberal</span> <span class="o">&&</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"Identifier"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-151"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-151">¶</a> </div> <p>Parses module export declaration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExport</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-152"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-152">¶</a> </div> <p>export var|const|let|function|class ...;</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_var</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_const</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_let</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_function</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_class</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">declaration</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span></pre></div> </td> </tr> <tr id="section-153"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-153">¶</a> </div> <p>export default ...;</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_default</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">declaration</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">semicolon</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-154"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-154">¶</a> </div> <p>export * from '...'
|
|
export { x, y as z } [from '...']</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isBatch</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_star</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">declaration</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span> <span class="o">=</span> <span class="nx">parseExportSpecifiers</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"from"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span> <span class="o">?</span> <span class="nx">parseExprAtom</span><span class="p">()</span> <span class="o">:</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">isBatch</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ExportDeclaration"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-155"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-155">¶</a> </div> <p>Parses a comma-separated list of module exports.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExportSpecifiers</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">nodes</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_star</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-156"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-156">¶</a> </div> <p>export * from '...'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ExportBatchSpecifier"</span><span class="p">));</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-157"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-157">¶</a> </div> <p>export { x, y as z } [from '...']</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"as"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ExportSpecifier"</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">nodes</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-158"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-158">¶</a> </div> <p>Parses import declaration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseImport</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-159"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-159">¶</a> </div> <p>import '...';</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">parseExprAtom</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span> <span class="o">=</span> <span class="nx">parseImportSpecifiers</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span> <span class="o">||</span> <span class="nx">tokVal</span> <span class="o">!==</span> <span class="s2">"from"</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span> <span class="o">?</span> <span class="nx">parseExprAtom</span><span class="p">()</span> <span class="o">:</span> <span class="nx">unexpected</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-160"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-160">¶</a> </div> <p>only for backward compatibility with Esprima's AST
|
|
(it doesn't support mixed default + named yet)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">node</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">specifiers</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">?</span> <span class="s2">"default"</span> <span class="o">:</span> <span class="s2">"named"</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ImportDeclaration"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-161"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-161">¶</a> </div> <p>Parses a comma-separated list of module imports.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseImportSpecifiers</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">nodes</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_star</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span> <span class="o">||</span> <span class="nx">tokVal</span> <span class="o">!==</span> <span class="s2">"as"</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ImportBatchSpecifier"</span><span class="p">));</span>
|
|
<span class="k">return</span> <span class="nx">nodes</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-162"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-162">¶</a> </div> <p>import defaultObj, { x, y as z } from '...'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ImportSpecifier"</span><span class="p">));</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="k">return</span> <span class="nx">nodes</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&&</span> <span class="nx">tokVal</span> <span class="o">===</span> <span class="s2">"as"</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">||</span> <span class="nx">node</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ImportSpecifier"</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">nodes</span><span class="p">;</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-163"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-163">¶</a> </div> <p>Parses yield expression inside generator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseYield</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">||</span> <span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">delegate</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">delegate</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_star</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"YieldExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-164"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-164">¶</a> </div> <p>Parses array and generator comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseComprehension</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isGenerator</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">blocks</span> <span class="o">=</span> <span class="p">[];</span>
|
|
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_for</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">block</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
|
|
<span class="nx">block</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">toAssignable</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">());</span>
|
|
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">block</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span> <span class="o">||</span> <span class="nx">tokVal</span> <span class="o">!==</span> <span class="s2">"of"</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
|
|
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-165"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-165">¶</a> </div> <p><code>of</code> property is here for compatibility with Esprima's AST
|
|
which also supports deprecated [for (... in ...) expr]</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">block</span><span class="p">.</span><span class="nx">of</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
|
<span class="nx">block</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">blocks</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">block</span><span class="p">,</span> <span class="s2">"ComprehensionBlock"</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">filter</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_if</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseParenExpression</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
|
|
<span class="nx">expect</span><span class="p">(</span><span class="nx">isGenerator</span> <span class="o">?</span> <span class="nx">_parenR</span> <span class="o">:</span> <span class="nx">_bracketR</span><span class="p">);</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">generator</span> <span class="o">=</span> <span class="nx">isGenerator</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ComprehensionExpression"</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="p">});</span>
|
|
|
|
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html> |