mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
rebuild annotated source documentation
This commit is contained in:
parent
094a0cbe95
commit
52b89d5b03
16 changed files with 5532 additions and 6193 deletions
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,14 +116,12 @@
|
|||
<p>This <strong>Browser</strong> compatibility layer extends core CoffeeScript functions
|
||||
to make things work smoothly when compiling code directly in the browser.
|
||||
We add support for loading remote Coffee scripts via <strong>XHR</strong>, and
|
||||
<code>text/coffeescript</code> script tags, source maps via data-URLs, and so on.
|
||||
</p>
|
||||
<code>text/coffeescript</code> script tags, source maps via data-URLs, and so on.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
CoffeeScript = require <span class="string">'./coffee-script'</span>
|
||||
CoffeeScript.require = require
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span>
|
||||
CoffeeScript.<span class="hljs-built_in">require</span> = <span class="hljs-built_in">require</span>
|
||||
compile = CoffeeScript.compile</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -130,13 +133,12 @@ compile = CoffeeScript.compile</pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>Use standard JavaScript <code>eval</code> to eval code.
|
||||
</p>
|
||||
<p>Use standard JavaScript <code>eval</code> to eval code.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="function"><span class="title">eval</span></span> = (code, options = {}) ->
|
||||
options.bare ?= <span class="literal">on</span>
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">eval</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||
options.bare ?= <span class="hljs-literal">on</span>
|
||||
eval compile code, options</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -148,14 +150,13 @@ compile = CoffeeScript.compile</pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Running code does not provide access to this scope.
|
||||
</p>
|
||||
<p>Running code does not provide access to this scope.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="function"><span class="title">run</span></span> = (code, options = {}) ->
|
||||
options.bare = <span class="literal">on</span>
|
||||
options.shiftLine = <span class="literal">on</span>
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">run</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||
options.bare = <span class="hljs-literal">on</span>
|
||||
options.shiftLine = <span class="hljs-literal">on</span>
|
||||
Function(compile code, options)()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -167,12 +168,11 @@ compile = CoffeeScript.compile</pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>If we're not in a browser environment, we're finished with the public API.
|
||||
</p>
|
||||
<p>If we're not in a browser environment, we're finished with the public API.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="keyword">return</span> <span class="keyword">unless</span> window?</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> <span class="hljs-built_in">window</span>?</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -185,17 +185,16 @@ compile = CoffeeScript.compile</pre></div></div>
|
|||
</div>
|
||||
<p>Include source maps where possible. If we've got a base64 encoder, a
|
||||
JSON serializer, and tools for escaping unicode characters, we're good to go.
|
||||
Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">https://developer.mozilla.org/en-US/docs/DOM/window.btoa</a>
|
||||
</p>
|
||||
Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">https://developer.mozilla.org/en-US/docs/DOM/window.btoa</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="keyword">if</span> btoa? <span class="keyword">and</span> JSON? <span class="keyword">and</span> unescape? <span class="keyword">and</span> encodeURIComponent?
|
||||
<span class="function"><span class="title">compile</span></span> = (code, options = {}) ->
|
||||
options.sourceMap = <span class="literal">true</span>
|
||||
options.inline = <span class="literal">true</span>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> btoa? <span class="hljs-keyword">and</span> JSON? <span class="hljs-keyword">and</span> unescape? <span class="hljs-keyword">and</span> encodeURIComponent?
|
||||
<span class="hljs-function"><span class="hljs-title">compile</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||
options.sourceMap = <span class="hljs-literal">true</span>
|
||||
options.inline = <span class="hljs-literal">true</span>
|
||||
{js, v3SourceMap} = CoffeeScript.compile code, options
|
||||
<span class="string">"<span class="subst">#{js}</span>\n//@ sourceMappingURL=data:application/json;base64,<span class="subst">#{btoa unescape encodeURIComponent v3SourceMap}</span>\n//@ sourceURL=coffeescript"</span></pre></div></div>
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{js}</span>\n//# sourceMappingURL=data:application/json;base64,<span class="hljs-subst">#{btoa unescape encodeURIComponent v3SourceMap}</span>\n//# sourceURL=coffeescript"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -206,27 +205,27 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Load a remote script from the current domain via XHR.
|
||||
</p>
|
||||
<p>Load a remote script from the current domain via XHR.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="function"><span class="title">load</span></span> = (url, callback, options = {}) ->
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">load</span> = <span class="hljs-params">(url, callback, options = {}, hold = <span class="hljs-literal">false</span>)</span> -></span>
|
||||
options.sourceFiles = [url]
|
||||
xhr = <span class="keyword">if</span> window.ActiveXObject
|
||||
<span class="keyword">new</span> window.ActiveXObject(<span class="string">'Microsoft.XMLHTTP'</span>)
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">new</span> window.XMLHttpRequest()
|
||||
xhr.open <span class="string">'GET'</span>, url, <span class="literal">true</span>
|
||||
xhr.overrideMimeType <span class="string">'text/plain'</span> <span class="keyword">if</span> <span class="string">'overrideMimeType'</span> <span class="keyword">of</span> xhr
|
||||
xhr.<span class="function"><span class="title">onreadystatechange</span></span> = ->
|
||||
<span class="keyword">if</span> xhr.readyState <span class="keyword">is</span> <span class="number">4</span>
|
||||
<span class="keyword">if</span> xhr.status <span class="keyword">in</span> [<span class="number">0</span>, <span class="number">200</span>]
|
||||
CoffeeScript.run xhr.responseText, options
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">throw</span> <span class="keyword">new</span> Error <span class="string">"Could not load <span class="subst">#{url}</span>"</span>
|
||||
callback() <span class="keyword">if</span> callback
|
||||
xhr.send <span class="literal">null</span></pre></div></div>
|
||||
xhr = <span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>.ActiveXObject
|
||||
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.ActiveXObject(<span class="hljs-string">'Microsoft.XMLHTTP'</span>)
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.XMLHttpRequest()
|
||||
xhr.open <span class="hljs-string">'GET'</span>, url, <span class="hljs-literal">true</span>
|
||||
xhr.overrideMimeType <span class="hljs-string">'text/plain'</span> <span class="hljs-keyword">if</span> <span class="hljs-string">'overrideMimeType'</span> <span class="hljs-keyword">of</span> xhr
|
||||
xhr.<span class="hljs-function"><span class="hljs-title">onreadystatechange</span> = -></span>
|
||||
<span class="hljs-keyword">if</span> xhr.readyState <span class="hljs-keyword">is</span> <span class="hljs-number">4</span>
|
||||
<span class="hljs-keyword">if</span> xhr.status <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, <span class="hljs-number">200</span>]
|
||||
param = [xhr.responseText, options]
|
||||
CoffeeScript.run param... <span class="hljs-keyword">unless</span> hold
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Could not load <span class="hljs-subst">#{url}</span>"</span>
|
||||
callback param <span class="hljs-keyword">if</span> callback
|
||||
xhr.send <span class="hljs-literal">null</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -239,29 +238,38 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||
</div>
|
||||
<p>Activate CoffeeScript in the browser by having it compile and evaluate
|
||||
all script tags with a content-type of <code>text/coffeescript</code>.
|
||||
This happens on page load.
|
||||
</p>
|
||||
This happens on page load.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">runScripts</span></span> = ->
|
||||
scripts = window.document.getElementsByTagName <span class="string">'script'</span>
|
||||
coffeetypes = [<span class="string">'text/coffeescript'</span>, <span class="string">'text/literate-coffeescript'</span>]
|
||||
coffees = (s <span class="keyword">for</span> s <span class="keyword">in</span> scripts <span class="keyword">when</span> s.type <span class="keyword">in</span> coffeetypes)
|
||||
index = <span class="number">0</span>
|
||||
length = coffees.length
|
||||
<span class="keyword">do</span> <span class="function"><span class="title">execute</span></span> = ->
|
||||
script = coffees[index++]
|
||||
mediatype = script?.type
|
||||
<span class="keyword">if</span> mediatype <span class="keyword">in</span> coffeetypes
|
||||
options = {literate: mediatype <span class="keyword">is</span> <span class="string">'text/literate-coffeescript'</span>}
|
||||
<span class="keyword">if</span> script.src
|
||||
CoffeeScript.load script.src, execute, options
|
||||
<span class="keyword">else</span>
|
||||
options.sourceFiles = [<span class="string">'embedded'</span>]
|
||||
CoffeeScript.run script.innerHTML, options
|
||||
execute()
|
||||
<span class="literal">null</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">runScripts</span> = -></span>
|
||||
scripts = <span class="hljs-built_in">window</span>.<span class="hljs-built_in">document</span>.getElementsByTagName <span class="hljs-string">'script'</span>
|
||||
coffeetypes = [<span class="hljs-string">'text/coffeescript'</span>, <span class="hljs-string">'text/literate-coffeescript'</span>]
|
||||
coffees = (s <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> scripts <span class="hljs-keyword">when</span> s.type <span class="hljs-keyword">in</span> coffeetypes)
|
||||
index = <span class="hljs-number">0</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">execute</span> = -></span>
|
||||
param = coffees[index]
|
||||
<span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Array
|
||||
CoffeeScript.run param...
|
||||
index++
|
||||
execute()
|
||||
|
||||
<span class="hljs-keyword">for</span> script, i <span class="hljs-keyword">in</span> coffees
|
||||
<span class="hljs-keyword">do</span> <span class="hljs-function"><span class="hljs-params">(script, i)</span> -></span>
|
||||
options = <span class="hljs-attribute">literate</span>: script.type <span class="hljs-keyword">is</span> coffeetypes[<span class="hljs-number">1</span>]
|
||||
<span class="hljs-keyword">if</span> script.src
|
||||
CoffeeScript.load script.src,
|
||||
<span class="hljs-function"><span class="hljs-params">(param)</span> -></span>
|
||||
coffees[i] = param
|
||||
execute()
|
||||
options
|
||||
<span class="hljs-literal">true</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
options.sourceFiles = [<span class="hljs-string">'embedded'</span>]
|
||||
coffees[i] = [script.innerHTML, options]
|
||||
|
||||
execute()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -272,15 +280,14 @@ This happens on page load.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Listen for window load, both in decent browsers and in IE.
|
||||
</p>
|
||||
<p>Listen for window load, both in decent browsers and in IE.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="keyword">if</span> window.addEventListener
|
||||
window.addEventListener <span class="string">'DOMContentLoaded'</span>, runScripts, <span class="literal">no</span>
|
||||
<span class="keyword">else</span>
|
||||
window.attachEvent <span class="string">'onload'</span>, runScripts</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>.addEventListener
|
||||
<span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'DOMContentLoaded'</span>, runScripts, <span class="hljs-literal">no</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-built_in">window</span>.attachEvent <span class="hljs-string">'onload'</span>, runScripts</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,15 +116,19 @@
|
|||
<p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
|
||||
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="http://github.com/280north/jake">Jake</a>)
|
||||
for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
|
||||
and can call them from the command line, or invoke them from other tasks.
|
||||
|
||||
</p>
|
||||
and can call them from the command line, or invoke them from other tasks.</p>
|
||||
<p>Running <code>cake</code> with no arguments will print out a list of all the tasks in the
|
||||
current directory's Cakefile.
|
||||
</p>
|
||||
current directory's Cakefile.</p>
|
||||
<p>External dependencies.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -129,18 +138,14 @@ current directory's Cakefile.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>External dependencies.
|
||||
</p>
|
||||
<p>Keep track of the list of defined tasks, the accepted options, and so on.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>fs = require <span class="string">'fs'</span>
|
||||
path = require <span class="string">'path'</span>
|
||||
helpers = require <span class="string">'./helpers'</span>
|
||||
optparse = require <span class="string">'./optparse'</span>
|
||||
CoffeeScript = require <span class="string">'./coffee-script'</span>
|
||||
|
||||
existsSync = fs.existsSync <span class="keyword">or</span> path.existsSync</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>tasks = {}
|
||||
options = {}
|
||||
switches = []
|
||||
oparse = <span class="hljs-literal">null</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -151,15 +156,11 @@ existsSync = fs.existsSync <span class="keyword">or</span> path.existsSync</pr
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Keep track of the list of defined tasks, the accepted options, and so on.
|
||||
</p>
|
||||
<p>Mixin the top-level Cake functions for Cakefiles to use directly.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>tasks = {}
|
||||
options = {}
|
||||
switches = []
|
||||
oparse = <span class="literal">null</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>helpers.extend <span class="hljs-built_in">global</span>,</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -170,12 +171,14 @@ oparse = <span class="literal">null</span></pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Mixin the top-level Cake functions for Cakefiles to use directly.
|
||||
</p>
|
||||
<p>Define a Cake task with a short name, an optional sentence description,
|
||||
and the function to run as the action itself.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>helpers.extend global,</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">task</span>: <span class="hljs-function"><span class="hljs-params">(name, description, action)</span> -></span>
|
||||
[action, description] = [description, action] <span class="hljs-keyword">unless</span> action
|
||||
tasks[name] = {name, description, action}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -186,15 +189,14 @@ oparse = <span class="literal">null</span></pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Define a Cake task with a short name, an optional sentence description,
|
||||
and the function to run as the action itself.
|
||||
</p>
|
||||
<p>Define an option that the Cakefile accepts. The parsed options hash,
|
||||
containing all of the command-line options passed, will be made available
|
||||
as the first argument to the action.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> task: (name, description, action) ->
|
||||
[action, description] = [description, action] <span class="keyword">unless</span> action
|
||||
tasks[name] = {name, description, action}</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">option</span>: <span class="hljs-function"><span class="hljs-params">(letter, flag, description)</span> -></span>
|
||||
switches.push [letter, flag, description]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -205,15 +207,13 @@ and the function to run as the action itself.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Define an option that the Cakefile accepts. The parsed options hash,
|
||||
containing all of the command-line options passed, will be made available
|
||||
as the first argument to the action.
|
||||
</p>
|
||||
<p>Invoke another task in the current Cakefile.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> option: (letter, flag, description) ->
|
||||
switches.push [letter, flag, description]</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">invoke</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||
missingTask name <span class="hljs-keyword">unless</span> tasks[name]
|
||||
tasks[name].action options</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -224,14 +224,25 @@ as the first argument to the action.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Invoke another task in the current Cakefile.
|
||||
</p>
|
||||
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node's
|
||||
asynchrony may cause tasks to execute in a different order than you'd expect.
|
||||
If no tasks are passed, print the help screen. Keep a reference to the
|
||||
original directory name, when running Cake tasks from subdirectories.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> invoke: (name) ->
|
||||
missingTask name <span class="keyword">unless</span> tasks[name]
|
||||
tasks[name].action options</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = -></span>
|
||||
<span class="hljs-built_in">global</span>.__originalDirname = fs.realpathSync <span class="hljs-string">'.'</span>
|
||||
process.chdir cakefileDirectory __originalDirname
|
||||
args = process.argv[<span class="hljs-number">2.</span>.]
|
||||
CoffeeScript.run fs.readFileSync(<span class="hljs-string">'Cakefile'</span>).toString(), <span class="hljs-attribute">filename</span>: <span class="hljs-string">'Cakefile'</span>
|
||||
oparse = <span class="hljs-keyword">new</span> optparse.OptionParser switches
|
||||
<span class="hljs-keyword">return</span> printTasks() <span class="hljs-keyword">unless</span> args.length
|
||||
<span class="hljs-keyword">try</span>
|
||||
options = oparse.parse(args)
|
||||
<span class="hljs-keyword">catch</span> e
|
||||
<span class="hljs-keyword">return</span> fatalError <span class="hljs-string">"<span class="hljs-subst">#{e}</span>"</span>
|
||||
invoke arg <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> options.arguments</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -242,26 +253,20 @@ as the first argument to the action.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node's
|
||||
asynchrony may cause tasks to execute in a different order than you'd expect.
|
||||
If no tasks are passed, print the help screen. Keep a reference to the
|
||||
original directory name, when running Cake tasks from subdirectories.
|
||||
</p>
|
||||
<p>Display the list of Cake tasks in a format similar to <code>rake -T</code></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">run</span></span> = ->
|
||||
global.__originalDirname = fs.realpathSync <span class="string">'.'</span>
|
||||
process.chdir cakefileDirectory __originalDirname
|
||||
args = process.argv[<span class="number">2.</span>.]
|
||||
CoffeeScript.run fs.readFileSync(<span class="string">'Cakefile'</span>).toString(), filename: <span class="string">'Cakefile'</span>
|
||||
oparse = <span class="keyword">new</span> optparse.OptionParser switches
|
||||
<span class="keyword">return</span> printTasks() <span class="keyword">unless</span> args.length
|
||||
<span class="keyword">try</span>
|
||||
options = oparse.parse(args)
|
||||
<span class="keyword">catch</span> e
|
||||
<span class="keyword">return</span> fatalError <span class="string">"<span class="subst">#{e}</span>"</span>
|
||||
invoke arg <span class="keyword">for</span> arg <span class="keyword">in</span> options.arguments</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTasks</span> = -></span>
|
||||
relative = path.relative <span class="hljs-keyword">or</span> path.resolve
|
||||
cakefilePath = path.join relative(__originalDirname, process.cwd()), <span class="hljs-string">'Cakefile'</span>
|
||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"<span class="hljs-subst">#{cakefilePath}</span> defines the following tasks:\n"</span>
|
||||
<span class="hljs-keyword">for</span> name, task <span class="hljs-keyword">of</span> tasks
|
||||
spaces = <span class="hljs-number">20</span> - name.length
|
||||
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> Array(spaces + <span class="hljs-number">1</span>).join(<span class="hljs-string">' '</span>) <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||
desc = <span class="hljs-keyword">if</span> task.description <span class="hljs-keyword">then</span> <span class="hljs-string">"# <span class="hljs-subst">#{task.description}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"cake <span class="hljs-subst">#{name}</span><span class="hljs-subst">#{spaces}</span> <span class="hljs-subst">#{desc}</span>"</span>
|
||||
<span class="hljs-built_in">console</span>.log oparse.help() <span class="hljs-keyword">if</span> switches.length</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -272,21 +277,16 @@ original directory name, when running Cake tasks from subdirectories.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Display the list of Cake tasks in a format similar to <code>rake -T</code>
|
||||
</p>
|
||||
<p>Print an error and exit when attempting to use an invalid task/option.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">printTasks</span></span> = ->
|
||||
relative = path.relative <span class="keyword">or</span> path.resolve
|
||||
cakefilePath = path.join relative(__originalDirname, process.cwd()), <span class="string">'Cakefile'</span>
|
||||
console.log <span class="string">"<span class="subst">#{cakefilePath}</span> defines the following tasks:\n"</span>
|
||||
<span class="keyword">for</span> name, task <span class="keyword">of</span> tasks
|
||||
spaces = <span class="number">20</span> - name.length
|
||||
spaces = <span class="keyword">if</span> spaces > <span class="number">0</span> <span class="keyword">then</span> Array(spaces + <span class="number">1</span>).join(<span class="string">' '</span>) <span class="keyword">else</span> <span class="string">''</span>
|
||||
desc = <span class="keyword">if</span> task.description <span class="keyword">then</span> <span class="string">"# <span class="subst">#{task.description}</span>"</span> <span class="keyword">else</span> <span class="string">''</span>
|
||||
console.log <span class="string">"cake <span class="subst">#{name}</span><span class="subst">#{spaces}</span> <span class="subst">#{desc}</span>"</span>
|
||||
console.log oparse.help() <span class="keyword">if</span> switches.length</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">fatalError</span> = <span class="hljs-params">(message)</span> -></span>
|
||||
<span class="hljs-built_in">console</span>.error message + <span class="hljs-string">'\n'</span>
|
||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">'To see a list of all tasks/options, run "cake"'</span>
|
||||
process.exit <span class="hljs-number">1</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">missingTask</span> = <span class="hljs-params">(task)</span> -></span> fatalError <span class="hljs-string">"No such task: <span class="hljs-subst">#{task}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -297,38 +297,16 @@ original directory name, when running Cake tasks from subdirectories.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Print an error and exit when attempting to use an invalid task/option.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">fatalError</span></span> = (message) ->
|
||||
console.error message + <span class="string">'\n'</span>
|
||||
console.log <span class="string">'To see a list of all tasks/options, run "cake"'</span>
|
||||
process.exit <span class="number">1</span>
|
||||
|
||||
<span class="function"><span class="title">missingTask</span></span> = (task) -> fatalError <span class="string">"No such task: <span class="subst">#{task}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-11">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>When <code>cake</code> is invoked, search in the current and all parent directories
|
||||
to find the relevant Cakefile.
|
||||
</p>
|
||||
to find the relevant Cakefile.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">cakefileDirectory</span></span> = (dir) ->
|
||||
<span class="keyword">return</span> dir <span class="keyword">if</span> existsSync path.join dir, <span class="string">'Cakefile'</span>
|
||||
parent = path.normalize path.join dir, <span class="string">'..'</span>
|
||||
<span class="keyword">return</span> cakefileDirectory parent <span class="keyword">unless</span> parent <span class="keyword">is</span> dir
|
||||
<span class="keyword">throw</span> <span class="keyword">new</span> Error <span class="string">"Cakefile not found in <span class="subst">#{process.cwd()}</span>"</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">cakefileDirectory</span> = <span class="hljs-params">(dir)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> dir <span class="hljs-keyword">if</span> fs.existsSync path.join dir, <span class="hljs-string">'Cakefile'</span>
|
||||
parent = path.normalize path.join dir, <span class="hljs-string">'..'</span>
|
||||
<span class="hljs-keyword">return</span> cakefileDirectory parent <span class="hljs-keyword">unless</span> parent <span class="hljs-keyword">is</span> dir
|
||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Cakefile not found in <span class="hljs-subst">#{process.cwd()}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,20 +116,17 @@
|
|||
<p>CoffeeScript can be used both on the server, as a command-line compiler based
|
||||
on Node.js/V8, or to run CoffeeScript directly in the browser. This module
|
||||
contains the main entry functions for tokenizing, parsing, and compiling
|
||||
source CoffeeScript into JavaScript.
|
||||
</p>
|
||||
source CoffeeScript into JavaScript.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
fs = require <span class="string">'fs'</span>
|
||||
vm = require <span class="string">'vm'</span>
|
||||
path = require <span class="string">'path'</span>
|
||||
child_process = require <span class="string">'child_process'</span>
|
||||
{Lexer} = require <span class="string">'./lexer'</span>
|
||||
{parser} = require <span class="string">'./parser'</span>
|
||||
helpers = require <span class="string">'./helpers'</span>
|
||||
SourceMap = require <span class="string">'./sourcemap'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||
{Lexer} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./lexer'</span>
|
||||
{parser} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./parser'</span>
|
||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
SourceMap = <span class="hljs-built_in">require</span> <span class="hljs-string">'./sourcemap'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -135,12 +137,13 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>The current CoffeeScript version number.
|
||||
</p>
|
||||
<p>The current CoffeeScript version number.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.VERSION = <span class="string">'1.6.3'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.VERSION = <span class="hljs-string">'1.7.0'</span>
|
||||
|
||||
<span class="hljs-built_in">exports</span>.FILE_EXTENSIONS = [<span class="hljs-string">'.coffee'</span>, <span class="hljs-string">'.litcoffee'</span>, <span class="hljs-string">'.coffee.md'</span>]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -151,12 +154,11 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Expose helpers for testing.
|
||||
</p>
|
||||
<p>Expose helpers for testing.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.helpers = helpers</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.helpers = helpers</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -167,35 +169,17 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
|
||||
|
||||
</p>
|
||||
<p>If <code>options.sourceMap</code> is specified, then <code>options.filename</code> must also be specified. All
|
||||
options that can be passed to <code>SourceMap#generate</code> may also be passed here.
|
||||
|
||||
</p>
|
||||
<p>This returns a javascript string, unless <code>options.sourceMap</code> is passed,
|
||||
in which case this returns a <code>{js, v3SourceMap, sourceMap}</code>
|
||||
object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for doing programatic
|
||||
lookups.
|
||||
</p>
|
||||
<p>Function wrapper to add source file information to SyntaxErrors thrown by the
|
||||
lexer/parser/compiler.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.compile = <span class="function"><span class="title">compile</span></span> = (code, options = {}) ->
|
||||
{merge} = helpers
|
||||
|
||||
<span class="keyword">if</span> options.sourceMap
|
||||
map = <span class="keyword">new</span> SourceMap
|
||||
|
||||
fragments = parser.parse(lexer.tokenize code, options).compileToFragments options
|
||||
|
||||
currentLine = <span class="number">0</span>
|
||||
currentLine += <span class="number">1</span> <span class="keyword">if</span> options.header
|
||||
currentLine += <span class="number">1</span> <span class="keyword">if</span> options.shiftLine
|
||||
currentColumn = <span class="number">0</span>
|
||||
js = <span class="string">""</span>
|
||||
<span class="keyword">for</span> fragment <span class="keyword">in</span> fragments</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">withPrettyErrors</span> = <span class="hljs-params">(fn)</span> -></span>
|
||||
<span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
fn.call @, code, options
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">throw</span> helpers.updateSyntaxError err, code, options.filename</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -206,20 +190,31 @@ lookups.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Update the sourcemap with data from each fragment
|
||||
</p>
|
||||
<p>Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.</p>
|
||||
<p>If <code>options.sourceMap</code> is specified, then <code>options.filename</code> must also be specified. All
|
||||
options that can be passed to <code>SourceMap#generate</code> may also be passed here.</p>
|
||||
<p>This returns a javascript string, unless <code>options.sourceMap</code> is passed,
|
||||
in which case this returns a <code>{js, v3SourceMap, sourceMap}</code>
|
||||
object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for doing programatic
|
||||
lookups.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> options.sourceMap
|
||||
<span class="keyword">if</span> fragment.locationData
|
||||
map.add(
|
||||
[fragment.locationData.first_line, fragment.locationData.first_column]
|
||||
[currentLine, currentColumn]
|
||||
{noReplace: <span class="literal">true</span>})
|
||||
newLines = helpers.count fragment.code, <span class="string">"\n"</span>
|
||||
currentLine += newLines
|
||||
currentColumn = fragment.code.length - (<span class="keyword">if</span> newLines <span class="keyword">then</span> fragment.code.lastIndexOf <span class="string">"\n"</span> <span class="keyword">else</span> <span class="number">0</span>)</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.compile = compile = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -></span>
|
||||
{merge, extend} = helpers
|
||||
options = extend {}, options
|
||||
|
||||
<span class="hljs-keyword">if</span> options.sourceMap
|
||||
map = <span class="hljs-keyword">new</span> SourceMap
|
||||
|
||||
fragments = parser.parse(lexer.tokenize code, options).compileToFragments options
|
||||
|
||||
currentLine = <span class="hljs-number">0</span>
|
||||
currentLine += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> options.header
|
||||
currentLine += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> options.shiftLine
|
||||
currentColumn = <span class="hljs-number">0</span>
|
||||
js = <span class="hljs-string">""</span>
|
||||
<span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> fragments</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -230,24 +225,22 @@ lookups.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Copy the code from each fragment into the final JavaScript.
|
||||
</p>
|
||||
<p>Update the sourcemap with data from each fragment</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> js += fragment.code
|
||||
|
||||
<span class="keyword">if</span> options.header
|
||||
header = <span class="string">"Generated by CoffeeScript <span class="subst">#{@VERSION}</span>"</span>
|
||||
js = <span class="string">"// <span class="subst">#{header}</span>\n<span class="subst">#{js}</span>"</span>
|
||||
|
||||
<span class="keyword">if</span> options.sourceMap
|
||||
answer = {js}
|
||||
answer.sourceMap = map
|
||||
answer.v3SourceMap = map.generate(options, code)
|
||||
answer
|
||||
<span class="keyword">else</span>
|
||||
js</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> options.sourceMap
|
||||
<span class="hljs-keyword">if</span> fragment.locationData
|
||||
map.add(
|
||||
[fragment.locationData.first_line, fragment.locationData.first_column]
|
||||
[currentLine, currentColumn]
|
||||
{<span class="hljs-attribute">noReplace</span>: <span class="hljs-literal">true</span>})
|
||||
newLines = helpers.count fragment.code, <span class="hljs-string">"\n"</span>
|
||||
currentLine += newLines
|
||||
<span class="hljs-keyword">if</span> newLines
|
||||
currentColumn = fragment.code.length - (fragment.code.lastIndexOf(<span class="hljs-string">"\n"</span>) + <span class="hljs-number">1</span>)
|
||||
<span class="hljs-keyword">else</span>
|
||||
currentColumn += fragment.code.length</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -258,13 +251,23 @@ lookups.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Tokenize a string of CoffeeScript code, and return the array of tokens.
|
||||
</p>
|
||||
<p>Copy the code from each fragment into the final JavaScript.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">tokens</span></span> = (code, options) ->
|
||||
lexer.tokenize code, options</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> js += fragment.code
|
||||
|
||||
<span class="hljs-keyword">if</span> options.header
|
||||
header = <span class="hljs-string">"Generated by CoffeeScript <span class="hljs-subst">#{<span class="hljs-property">@VERSION</span>}</span>"</span>
|
||||
js = <span class="hljs-string">"// <span class="hljs-subst">#{header}</span>\n<span class="hljs-subst">#{js}</span>"</span>
|
||||
|
||||
<span class="hljs-keyword">if</span> options.sourceMap
|
||||
answer = {js}
|
||||
answer.sourceMap = map
|
||||
answer.v3SourceMap = map.generate(options, code)
|
||||
answer
|
||||
<span class="hljs-keyword">else</span>
|
||||
js</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -275,18 +278,12 @@ lookups.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Parse a string of CoffeeScript code or an array of lexed tokens, and
|
||||
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
|
||||
or traverse it by using <code>.traverseChildren()</code> with a callback.
|
||||
</p>
|
||||
<p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">nodes</span></span> = (source, options) ->
|
||||
<span class="keyword">if</span> <span class="keyword">typeof</span> source <span class="keyword">is</span> <span class="string">'string'</span>
|
||||
parser.parse lexer.tokenize source, options
|
||||
<span class="keyword">else</span>
|
||||
parser.parse source</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.tokens = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -></span>
|
||||
lexer.tokenize code, options</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -297,15 +294,17 @@ or traverse it by using <code>.traverseChildren()</code> with a callback.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Compile and execute a string of CoffeeScript (on the server), correctly
|
||||
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.
|
||||
</p>
|
||||
<p>Parse a string of CoffeeScript code or an array of lexed tokens, and
|
||||
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
|
||||
or traverse it by using <code>.traverseChildren()</code> with a callback.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">run</span></span> = (code, options = {}) ->
|
||||
mainModule = require.main
|
||||
options.sourceMap ?= <span class="literal">true</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.nodes = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(source, options)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span> source <span class="hljs-keyword">is</span> <span class="hljs-string">'string'</span>
|
||||
parser.parse lexer.tokenize source, options
|
||||
<span class="hljs-keyword">else</span>
|
||||
parser.parse source</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -316,13 +315,13 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Set the filename.
|
||||
</p>
|
||||
<p>Compile and execute a string of CoffeeScript (on the server), correctly
|
||||
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> mainModule.filename = process.argv[<span class="number">1</span>] =
|
||||
<span class="keyword">if</span> options.filename <span class="keyword">then</span> fs.realpathSync(options.filename) <span class="keyword">else</span> <span class="string">'.'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||
mainModule = <span class="hljs-built_in">require</span>.main</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -333,12 +332,12 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Clear the module cache.
|
||||
</p>
|
||||
<p>Set the filename.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> mainModule.moduleCache <span class="keyword">and</span>= {}</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> mainModule.filename = process.argv[<span class="hljs-number">1</span>] =
|
||||
<span class="hljs-keyword">if</span> options.filename <span class="hljs-keyword">then</span> fs.realpathSync(options.filename) <span class="hljs-keyword">else</span> <span class="hljs-string">'.'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -349,12 +348,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>Assign paths for node_modules loading
|
||||
</p>
|
||||
<p>Clear the module cache.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> mainModule.paths = require(<span class="string">'module'</span>)._nodeModulePaths path.dirname fs.realpathSync options.filename <span class="keyword">or</span> <span class="string">'.'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> mainModule.moduleCache <span class="hljs-keyword">and</span>= {}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -365,13 +363,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Compile.
|
||||
</p>
|
||||
<p>Assign paths for node_modules loading</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> <span class="keyword">not</span> helpers.isCoffee(mainModule.filename) <span class="keyword">or</span> require.extensions
|
||||
answer = compile(code, options)</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> dir = <span class="hljs-keyword">if</span> options.filename
|
||||
path.dirname fs.realpathSync options.filename
|
||||
<span class="hljs-keyword">else</span>
|
||||
fs.realpathSync <span class="hljs-string">'.'</span>
|
||||
mainModule.paths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'module'</span>)._nodeModulePaths dir</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -382,17 +382,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Attach sourceMap object to sourceMaps[options.filename] so that
|
||||
it is accessible by Error.prepareStackTrace.
|
||||
</p>
|
||||
<p>Compile.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">do</span> patchStackTrace
|
||||
sourceMaps[mainModule.filename] = answer.sourceMap
|
||||
mainModule._compile answer.js, mainModule.filename
|
||||
<span class="keyword">else</span>
|
||||
mainModule._compile code, mainModule.filename</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> helpers.isCoffee(mainModule.filename) <span class="hljs-keyword">or</span> <span class="hljs-built_in">require</span>.extensions
|
||||
answer = compile code, options
|
||||
code = answer.js ? answer
|
||||
|
||||
mainModule._compile code, mainModule.filename</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -404,25 +402,24 @@ it is accessible by Error.prepareStackTrace.
|
|||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
||||
The CoffeeScript REPL uses this to run the input.
|
||||
</p>
|
||||
The CoffeeScript REPL uses this to run the input.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">eval</span></span> = (code, options = {}) ->
|
||||
<span class="keyword">return</span> <span class="keyword">unless</span> code = code.trim()
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">eval</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> code = code.trim()
|
||||
Script = vm.Script
|
||||
<span class="keyword">if</span> Script
|
||||
<span class="keyword">if</span> options.sandbox?
|
||||
<span class="keyword">if</span> options.sandbox <span class="keyword">instanceof</span> Script.createContext().constructor
|
||||
<span class="hljs-keyword">if</span> Script
|
||||
<span class="hljs-keyword">if</span> options.sandbox?
|
||||
<span class="hljs-keyword">if</span> options.sandbox <span class="hljs-keyword">instanceof</span> Script.createContext().constructor
|
||||
sandbox = options.sandbox
|
||||
<span class="keyword">else</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
sandbox = Script.createContext()
|
||||
sandbox[k] = v <span class="keyword">for</span> own k, v <span class="keyword">of</span> options.sandbox
|
||||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
|
||||
<span class="keyword">else</span>
|
||||
sandbox = global
|
||||
sandbox.__filename = options.filename || <span class="string">'eval'</span>
|
||||
sandbox[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options.sandbox
|
||||
sandbox.<span class="hljs-built_in">global</span> = sandbox.root = sandbox.GLOBAL = sandbox
|
||||
<span class="hljs-keyword">else</span>
|
||||
sandbox = <span class="hljs-built_in">global</span>
|
||||
sandbox.__filename = options.filename || <span class="hljs-string">'eval'</span>
|
||||
sandbox.__dirname = path.dirname sandbox.__filename</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -434,17 +431,16 @@ The CoffeeScript REPL uses this to run the input.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>define module/require only if they chose not to specify their own
|
||||
</p>
|
||||
<p>define module/require only if they chose not to specify their own</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">unless</span> sandbox <span class="keyword">isnt</span> global <span class="keyword">or</span> sandbox.module <span class="keyword">or</span> sandbox.require
|
||||
Module = require <span class="string">'module'</span>
|
||||
sandbox.module = _module = <span class="keyword">new</span> Module(options.modulename || <span class="string">'eval'</span>)
|
||||
sandbox.require = <span class="function"><span class="title">_require</span></span> = (path) -> Module._load path, _module, <span class="literal">true</span>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> sandbox <span class="hljs-keyword">isnt</span> <span class="hljs-built_in">global</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">module</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">require</span>
|
||||
Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||
sandbox.<span class="hljs-built_in">module</span> = _module = <span class="hljs-keyword">new</span> Module(options.modulename || <span class="hljs-string">'eval'</span>)
|
||||
sandbox.<span class="hljs-built_in">require</span> = <span class="hljs-function"><span class="hljs-title">_require</span> = <span class="hljs-params">(path)</span> -></span> Module._load path, _module, <span class="hljs-literal">true</span>
|
||||
_module.filename = sandbox.__filename
|
||||
_require[r] = require[r] <span class="keyword">for</span> r <span class="keyword">in</span> Object.getOwnPropertyNames require <span class="keyword">when</span> r <span class="keyword">isnt</span> <span class="string">'paths'</span></pre></div></div>
|
||||
_require[r] = <span class="hljs-built_in">require</span>[r] <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Object.getOwnPropertyNames <span class="hljs-built_in">require</span> <span class="hljs-keyword">when</span> r <span class="hljs-keyword">isnt</span> <span class="hljs-string">'paths'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -455,21 +451,30 @@ The CoffeeScript REPL uses this to run the input.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>use the same hack node currently uses for their own REPL
|
||||
</p>
|
||||
<p>use the same hack node currently uses for their own REPL</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
|
||||
_require.<span class="function"><span class="title">resolve</span></span> = (request) -> Module._resolveFilename request, _module
|
||||
_require.<span class="hljs-function"><span class="hljs-title">resolve</span> = <span class="hljs-params">(request)</span> -></span> Module._resolveFilename request, _module
|
||||
o = {}
|
||||
o[k] = v <span class="keyword">for</span> own k, v <span class="keyword">of</span> options
|
||||
o.bare = <span class="literal">on</span> <span class="comment"># ensure return value</span>
|
||||
o[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options
|
||||
o.bare = <span class="hljs-literal">on</span> <span class="hljs-comment"># ensure return value</span>
|
||||
js = compile code, o
|
||||
<span class="keyword">if</span> sandbox <span class="keyword">is</span> global
|
||||
<span class="hljs-keyword">if</span> sandbox <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
|
||||
vm.runInThisContext js
|
||||
<span class="keyword">else</span>
|
||||
vm.runInContext js, sandbox</pre></div></div>
|
||||
<span class="hljs-keyword">else</span>
|
||||
vm.runInContext js, sandbox
|
||||
|
||||
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">register</span> = -></span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./register'</span>
|
||||
|
||||
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">_compileFile</span> = <span class="hljs-params">(filename, sourceMap = <span class="hljs-literal">no</span>)</span> -></span>
|
||||
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span>
|
||||
stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
|
||||
|
||||
<span class="hljs-keyword">try</span>
|
||||
answer = compile(stripped, {filename, sourceMap, <span class="hljs-attribute">literate</span>: helpers.isLiterate filename})
|
||||
<span class="hljs-keyword">catch</span> err</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -480,17 +485,15 @@ The CoffeeScript REPL uses this to run the input.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.
|
||||
</p>
|
||||
<p>As the filename and code of a dynamically loaded file will be different
|
||||
from the original file compiled with CoffeeScript.run, add that
|
||||
information to error so it can be pretty-printed later.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">loadFile</span></span> = (module, filename) ->
|
||||
raw = fs.readFileSync filename, <span class="string">'utf8'</span>
|
||||
stripped = <span class="keyword">if</span> raw.charCodeAt(<span class="number">0</span>) <span class="keyword">is</span> <span class="number">0xFEFF</span> <span class="keyword">then</span> raw.substring <span class="number">1</span> <span class="keyword">else</span> raw
|
||||
answer = compile(stripped, {filename, sourceMap: <span class="literal">true</span>, literate: helpers.isLiterate filename})
|
||||
sourceMaps[filename] = answer.sourceMap
|
||||
module._compile answer.js, filename</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> helpers.updateSyntaxError err, stripped, filename
|
||||
|
||||
answer</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -501,15 +504,11 @@ The CoffeeScript REPL uses this to run the input.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>If the installed version of Node supports <code>require.extensions</code>, register
|
||||
CoffeeScript as an extension.
|
||||
</p>
|
||||
<p>Instantiate a Lexer for our use here.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="keyword">if</span> require.extensions
|
||||
<span class="keyword">for</span> ext <span class="keyword">in</span> [<span class="string">'.coffee'</span>, <span class="string">'.litcoffee'</span>, <span class="string">'.coffee.md'</span>]
|
||||
require.extensions[ext] = loadFile</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>lexer = <span class="hljs-keyword">new</span> Lexer</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -520,18 +519,27 @@ CoffeeScript as an extension.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>Patch Node's module loader to be able to handle mult-dot extensions.
|
||||
This is a horrible thing that should not be required. Perhaps, one day,
|
||||
when a truly benevolent dictator comes to rule over the Republik of Node,
|
||||
it won't be.
|
||||
</p>
|
||||
<p>The real Lexer produces a generic stream of tokens. This object provides a
|
||||
thin wrapper around it, compatible with the Jison API. We can then pass it
|
||||
directly as a "Jison lexer".</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> Module = require <span class="string">'module'</span>
|
||||
<div class="content"><div class='highlight'><pre>parser.lexer =
|
||||
<span class="hljs-attribute">lex</span>:<span class="hljs-function"> -></span>
|
||||
token = <span class="hljs-property">@tokens</span>[<span class="hljs-property">@pos</span>++]
|
||||
<span class="hljs-keyword">if</span> token
|
||||
[tag, <span class="hljs-property">@yytext</span>, <span class="hljs-property">@yylloc</span>] = token
|
||||
<span class="hljs-property">@errorToken</span> = token.origin <span class="hljs-keyword">or</span> token
|
||||
<span class="hljs-property">@yylineno</span> = <span class="hljs-property">@yylloc</span>.first_line
|
||||
<span class="hljs-keyword">else</span>
|
||||
tag = <span class="hljs-string">''</span>
|
||||
|
||||
<span class="function"><span class="title">findExtension</span></span> = (filename) ->
|
||||
extensions = path.basename(filename).split <span class="string">'.'</span></pre></div></div>
|
||||
tag
|
||||
<span class="hljs-attribute">setInput</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@tokens</span>)</span> -></span>
|
||||
<span class="hljs-property">@pos</span> = <span class="hljs-number">0</span>
|
||||
<span class="hljs-attribute">upcomingInput</span>:<span class="hljs-function"> -></span>
|
||||
<span class="hljs-string">""</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -542,12 +550,11 @@ it won't be.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>Remove the initial dot from dotfiles.
|
||||
</p>
|
||||
<p>Make all the AST nodes visible to the parser.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> extensions.shift() <span class="keyword">if</span> extensions[<span class="number">0</span>] <span class="keyword">is</span> <span class="string">''</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>parser.yy = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -558,22 +565,11 @@ it won't be.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-22">¶</a>
|
||||
</div>
|
||||
<p>Start with the longest possible extension and work our way shortwards.
|
||||
</p>
|
||||
<p>Override Jison's default error handling function.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">while</span> extensions.shift()
|
||||
curExtension = <span class="string">'.'</span> + extensions.join <span class="string">'.'</span>
|
||||
<span class="keyword">return</span> curExtension <span class="keyword">if</span> Module._extensions[curExtension]
|
||||
<span class="string">'.js'</span>
|
||||
|
||||
Module::<span class="function"><span class="title">load</span></span> = (filename) ->
|
||||
<span class="property">@filename</span> = filename
|
||||
<span class="property">@paths</span> = Module._nodeModulePaths path.dirname filename
|
||||
extension = findExtension filename
|
||||
Module._extensions[extension](<span class="keyword">this</span>, filename)
|
||||
<span class="property">@loaded</span> = <span class="literal">true</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>parser.yy.<span class="hljs-function"><span class="hljs-title">parseError</span> = <span class="hljs-params">(message, {token})</span> -></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -584,21 +580,21 @@ it won't be.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-23">¶</a>
|
||||
</div>
|
||||
<p>If we're on Node, patch <code>child_process.fork</code> so that Coffee scripts are able
|
||||
to fork both CoffeeScript files, and JavaScript files, directly.
|
||||
</p>
|
||||
<p>Disregard Jison's message, it contains redundant line numer information.
|
||||
Disregard the token, we take its value directly from the lexer in case
|
||||
the error is caused by a generated token which might refer to its origin.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="keyword">if</span> child_process
|
||||
{fork} = child_process
|
||||
child_process.<span class="function"><span class="title">fork</span></span> = (path, args = [], options = {}) ->
|
||||
execPath = <span class="keyword">if</span> helpers.isCoffee(path) <span class="keyword">then</span> <span class="string">'coffee'</span> <span class="keyword">else</span> <span class="literal">null</span>
|
||||
<span class="keyword">if</span> <span class="keyword">not</span> Array.isArray args
|
||||
args = []
|
||||
options = args <span class="keyword">or</span> {}
|
||||
options.execPath <span class="keyword">or</span>= execPath
|
||||
fork path, args, options</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> {errorToken, tokens} = parser.lexer
|
||||
[errorTag, errorText, errorLoc] = errorToken
|
||||
|
||||
errorText = <span class="hljs-keyword">if</span> errorToken <span class="hljs-keyword">is</span> tokens[tokens.length - <span class="hljs-number">1</span>]
|
||||
<span class="hljs-string">'end of input'</span>
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> errorTag <span class="hljs-keyword">in</span> [<span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'OUTDENT'</span>]
|
||||
<span class="hljs-string">'indentation'</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
helpers.nameWhitespaceCharacter errorText</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -609,12 +605,14 @@ to fork both CoffeeScript files, and JavaScript files, directly.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-24">¶</a>
|
||||
</div>
|
||||
<p>Instantiate a Lexer for our use here.
|
||||
</p>
|
||||
<p>The second argument has a <code>loc</code> property, which should have the location
|
||||
data for this token. Unfortunately, Jison seems to send an outdated <code>loc</code>
|
||||
(from the previous token), so we take the location information directly
|
||||
from the lexer.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>lexer = <span class="keyword">new</span> Lexer</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> helpers.throwSyntaxError <span class="hljs-string">"unexpected <span class="hljs-subst">#{errorText}</span>"</span>, errorLoc</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -625,27 +623,28 @@ to fork both CoffeeScript files, and JavaScript files, directly.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-25">¶</a>
|
||||
</div>
|
||||
<p>The real Lexer produces a generic stream of tokens. This object provides a
|
||||
thin wrapper around it, compatible with the Jison API. We can then pass it
|
||||
directly as a "Jison lexer".
|
||||
</p>
|
||||
<p>Based on <a href="http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js">http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js</a>
|
||||
Modified to handle sourceMap</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>parser.lexer =
|
||||
lex: ->
|
||||
token = <span class="property">@tokens</span>[<span class="property">@pos</span>++]
|
||||
<span class="keyword">if</span> token
|
||||
[tag, <span class="property">@yytext</span>, <span class="property">@yylloc</span>] = token
|
||||
<span class="property">@yylineno</span> = <span class="property">@yylloc</span>.first_line
|
||||
<span class="keyword">else</span>
|
||||
tag = <span class="string">''</span>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">formatSourcePosition</span> = <span class="hljs-params">(frame, getSourceMapping)</span> -></span>
|
||||
fileName = <span class="hljs-literal">undefined</span>
|
||||
fileLocation = <span class="hljs-string">''</span>
|
||||
|
||||
tag
|
||||
setInput: (<span class="property">@tokens</span>) ->
|
||||
<span class="property">@pos</span> = <span class="number">0</span>
|
||||
upcomingInput: ->
|
||||
<span class="string">""</span></pre></div></div>
|
||||
<span class="hljs-keyword">if</span> frame.isNative()
|
||||
fileLocation = <span class="hljs-string">"native"</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-keyword">if</span> frame.isEval()
|
||||
fileName = frame.getScriptNameOrSourceURL()
|
||||
fileLocation = <span class="hljs-string">"<span class="hljs-subst">#{frame.getEvalOrigin()}</span>, "</span> <span class="hljs-keyword">unless</span> fileName
|
||||
<span class="hljs-keyword">else</span>
|
||||
fileName = frame.getFileName()
|
||||
|
||||
fileName <span class="hljs-keyword">or</span>= <span class="hljs-string">"<anonymous>"</span>
|
||||
|
||||
line = frame.getLineNumber()
|
||||
column = frame.getColumnNumber()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -656,12 +655,41 @@ directly as a "Jison lexer".
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-26">¶</a>
|
||||
</div>
|
||||
<p>Make all the AST nodes visible to the parser.
|
||||
</p>
|
||||
<p>Check for a sourceMap position</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>parser.yy = require <span class="string">'./nodes'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> source = getSourceMapping fileName, line, column
|
||||
fileLocation =
|
||||
<span class="hljs-keyword">if</span> source
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{fileName}</span>:<span class="hljs-subst">#{source[<span class="hljs-number">0</span>]}</span>:<span class="hljs-subst">#{source[<span class="hljs-number">1</span>]}</span>"</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{fileName}</span>:<span class="hljs-subst">#{line}</span>:<span class="hljs-subst">#{column}</span>"</span>
|
||||
|
||||
functionName = frame.getFunctionName()
|
||||
isConstructor = frame.isConstructor()
|
||||
isMethodCall = <span class="hljs-keyword">not</span> (frame.isToplevel() <span class="hljs-keyword">or</span> isConstructor)
|
||||
|
||||
<span class="hljs-keyword">if</span> isMethodCall
|
||||
methodName = frame.getMethodName()
|
||||
typeName = frame.getTypeName()
|
||||
|
||||
<span class="hljs-keyword">if</span> functionName
|
||||
tp = as = <span class="hljs-string">''</span>
|
||||
<span class="hljs-keyword">if</span> typeName <span class="hljs-keyword">and</span> functionName.indexOf typeName
|
||||
tp = <span class="hljs-string">"<span class="hljs-subst">#{typeName}</span>."</span>
|
||||
<span class="hljs-keyword">if</span> methodName <span class="hljs-keyword">and</span> functionName.indexOf(<span class="hljs-string">".<span class="hljs-subst">#{methodName}</span>"</span>) <span class="hljs-keyword">isnt</span> functionName.length - methodName.length - <span class="hljs-number">1</span>
|
||||
as = <span class="hljs-string">" [as <span class="hljs-subst">#{methodName}</span>]"</span>
|
||||
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{tp}</span><span class="hljs-subst">#{functionName}</span><span class="hljs-subst">#{as}</span> (<span class="hljs-subst">#{fileLocation}</span>)"</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{typeName}</span>.<span class="hljs-subst">#{methodName <span class="hljs-keyword">or</span> <span class="hljs-string">'<anonymous>'</span>}</span> (<span class="hljs-subst">#{fileLocation}</span>)"</span>
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> isConstructor
|
||||
<span class="hljs-string">"new <span class="hljs-subst">#{functionName <span class="hljs-keyword">or</span> <span class="hljs-string">'<anonymous>'</span>}</span> (<span class="hljs-subst">#{fileLocation}</span>)"</span>
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> functionName
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{functionName}</span> (<span class="hljs-subst">#{fileLocation}</span>)"</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
fileLocation</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -672,12 +700,11 @@ directly as a "Jison lexer".
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-27">¶</a>
|
||||
</div>
|
||||
<p>Override Jison's default error handling function.
|
||||
</p>
|
||||
<p>Map of filenames -> sourceMap object.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>parser.yy.<span class="function"><span class="title">parseError</span></span> = (message, {token}) -></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>sourceMaps = {}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -688,12 +715,15 @@ directly as a "Jison lexer".
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-28">¶</a>
|
||||
</div>
|
||||
<p>Disregard Jison's message, it contains redundant line numer information.
|
||||
</p>
|
||||
<p>Generates the source map for a coffee file and stores it in the local cache variable.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> message = <span class="string">"unexpected <span class="subst">#{<span class="keyword">if</span> token <span class="keyword">is</span> <span class="number">1</span> <span class="keyword">then</span> 'end <span class="keyword">of</span> input' <span class="keyword">else</span> token}</span>"</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getSourceMap</span> = <span class="hljs-params">(filename)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> sourceMaps[filename] <span class="hljs-keyword">if</span> sourceMaps[filename]
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> path?.extname(filename) <span class="hljs-keyword">in</span> <span class="hljs-built_in">exports</span>.FILE_EXTENSIONS
|
||||
answer = <span class="hljs-built_in">exports</span>._compileFile filename, <span class="hljs-literal">true</span>
|
||||
sourceMaps[filename] = answer.sourceMap</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -704,167 +734,24 @@ directly as a "Jison lexer".
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-29">¶</a>
|
||||
</div>
|
||||
<p>The second argument has a <code>loc</code> property, which should have the location
|
||||
data for this token. Unfortunately, Jison seems to send an outdated <code>loc</code>
|
||||
(from the previous token), so we take the location information directly
|
||||
from the lexer.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> helpers.throwSyntaxError message, parser.lexer.yylloc</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-30">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-30">¶</a>
|
||||
</div>
|
||||
<p>Based on <a href="http://goo.gl/ZTx1p">michaelficarra/CoffeeScriptRedux</a>
|
||||
NodeJS / V8 have no support for transforming positions in stack traces using
|
||||
sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
||||
positions.
|
||||
</p>
|
||||
positions.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
patched = <span class="literal">false</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>Error.<span class="hljs-function"><span class="hljs-title">prepareStackTrace</span> = <span class="hljs-params">(err, stack)</span> -></span>
|
||||
<span class="hljs-function"><span class="hljs-title">getSourceMapping</span> = <span class="hljs-params">(filename, line, column)</span> -></span>
|
||||
sourceMap = getSourceMap filename
|
||||
answer = sourceMap.sourceLocation [line - <span class="hljs-number">1</span>, column - <span class="hljs-number">1</span>] <span class="hljs-keyword">if</span> sourceMap
|
||||
<span class="hljs-keyword">if</span> answer <span class="hljs-keyword">then</span> [answer[<span class="hljs-number">0</span>] + <span class="hljs-number">1</span>, answer[<span class="hljs-number">1</span>] + <span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
|
||||
|
||||
</li>
|
||||
frames = <span class="hljs-keyword">for</span> frame <span class="hljs-keyword">in</span> stack
|
||||
<span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> frame.getFunction() <span class="hljs-keyword">is</span> <span class="hljs-built_in">exports</span>.run
|
||||
<span class="hljs-string">" at <span class="hljs-subst">#{formatSourcePosition frame, getSourceMapping}</span>"</span>
|
||||
|
||||
|
||||
<li id="section-31">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-31">¶</a>
|
||||
</div>
|
||||
<p>Map of filenames -> sourceMap object.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>sourceMaps = {}
|
||||
|
||||
<span class="function"><span class="title">patchStackTrace</span></span> = ->
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> patched
|
||||
patched = <span class="literal">true</span>
|
||||
mainModule = require.main</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-32">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-32">¶</a>
|
||||
</div>
|
||||
<p>(Assigning to a property of the Module object in the normal module cache is
|
||||
unsuitable, because node deletes those objects from the cache if an
|
||||
exception is thrown in the module body.)
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
Error.<span class="function"><span class="title">prepareStackTrace</span></span> = (err, stack) ->
|
||||
sourceFiles = {}
|
||||
|
||||
<span class="function"><span class="title">getSourceMapping</span></span> = (filename, line, column) ->
|
||||
sourceMap = sourceMaps[filename]
|
||||
answer = sourceMap.sourceLocation [line - <span class="number">1</span>, column - <span class="number">1</span>] <span class="keyword">if</span> sourceMap
|
||||
<span class="keyword">if</span> answer <span class="keyword">then</span> [answer[<span class="number">0</span>] + <span class="number">1</span>, answer[<span class="number">1</span>] + <span class="number">1</span>] <span class="keyword">else</span> <span class="literal">null</span>
|
||||
|
||||
frames = <span class="keyword">for</span> frame <span class="keyword">in</span> stack
|
||||
<span class="keyword">break</span> <span class="keyword">if</span> frame.getFunction() <span class="keyword">is</span> exports.run
|
||||
<span class="string">" at <span class="subst">#{formatSourcePosition frame, getSourceMapping}</span>"</span>
|
||||
|
||||
<span class="string">"<span class="subst">#{err.name}</span>: <span class="subst">#{err.message ? ''}</span>\n<span class="subst">#{frames.join '\n'}</span>\n"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-33">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-33">¶</a>
|
||||
</div>
|
||||
<p>Based on <a href="http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js">http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js</a>
|
||||
Modified to handle sourceMap
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">formatSourcePosition</span></span> = (frame, getSourceMapping) ->
|
||||
fileName = <span class="literal">undefined</span>
|
||||
fileLocation = <span class="string">''</span>
|
||||
|
||||
<span class="keyword">if</span> frame.isNative()
|
||||
fileLocation = <span class="string">"native"</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">if</span> frame.isEval()
|
||||
fileName = frame.getScriptNameOrSourceURL()
|
||||
fileLocation = <span class="string">"<span class="subst">#{frame.getEvalOrigin()}</span>, "</span> <span class="keyword">unless</span> fileName
|
||||
<span class="keyword">else</span>
|
||||
fileName = frame.getFileName()
|
||||
|
||||
fileName <span class="keyword">or</span>= <span class="string">"<anonymous>"</span>
|
||||
|
||||
line = frame.getLineNumber()
|
||||
column = frame.getColumnNumber()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-34">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-34">¶</a>
|
||||
</div>
|
||||
<p>Check for a sourceMap position
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> source = getSourceMapping fileName, line, column
|
||||
fileLocation =
|
||||
<span class="keyword">if</span> source
|
||||
<span class="string">"<span class="subst">#{fileName}</span>:<span class="subst">#{source[<span class="number">0</span>]}</span>:<span class="subst">#{source[<span class="number">1</span>]}</span>, <js>:<span class="subst">#{line}</span>:<span class="subst">#{column}</span>"</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="string">"<span class="subst">#{fileName}</span>:<span class="subst">#{line}</span>:<span class="subst">#{column}</span>"</span>
|
||||
|
||||
|
||||
functionName = frame.getFunctionName()
|
||||
isConstructor = frame.isConstructor()
|
||||
isMethodCall = <span class="keyword">not</span> (frame.isToplevel() <span class="keyword">or</span> isConstructor)
|
||||
|
||||
<span class="keyword">if</span> isMethodCall
|
||||
methodName = frame.getMethodName()
|
||||
typeName = frame.getTypeName()
|
||||
|
||||
<span class="keyword">if</span> functionName
|
||||
tp = as = <span class="string">''</span>
|
||||
<span class="keyword">if</span> typeName <span class="keyword">and</span> functionName.indexOf typeName
|
||||
tp = <span class="string">"<span class="subst">#{typeName}</span>."</span>
|
||||
<span class="keyword">if</span> methodName <span class="keyword">and</span> functionName.indexOf(<span class="string">".<span class="subst">#{methodName}</span>"</span>) <span class="keyword">isnt</span> functionName.length - methodName.length - <span class="number">1</span>
|
||||
as = <span class="string">" [as <span class="subst">#{methodName}</span>]"</span>
|
||||
|
||||
<span class="string">"<span class="subst">#{tp}</span><span class="subst">#{functionName}</span><span class="subst">#{as}</span> (<span class="subst">#{fileLocation}</span>)"</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="string">"<span class="subst">#{typeName}</span>.<span class="subst">#{methodName <span class="keyword">or</span> '<anonymous>'}</span> (<span class="subst">#{fileLocation}</span>)"</span>
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> isConstructor
|
||||
<span class="string">"new <span class="subst">#{functionName <span class="keyword">or</span> '<anonymous>'}</span> (<span class="subst">#{fileLocation}</span>)"</span>
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> functionName
|
||||
<span class="string">"<span class="subst">#{functionName}</span> (<span class="subst">#{fileLocation}</span>)"</span>
|
||||
<span class="keyword">else</span>
|
||||
fileLocation</pre></div></div>
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{err.name}</span>: <span class="hljs-subst">#{err.message ? <span class="hljs-string">''</span>}</span>\n<span class="hljs-subst">#{frames.join <span class="hljs-string">'\n'</span>}</span>\n"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -112,11 +117,22 @@
|
|||
into various forms: saved into <code>.js</code> files or printed to stdout
|
||||
or recompiled every time the source is saved,
|
||||
printed as a token stream or as the syntax tree, or launch an
|
||||
interactive REPL.
|
||||
</p>
|
||||
interactive REPL.</p>
|
||||
<p>External dependencies.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span>
|
||||
mkdirp = <span class="hljs-built_in">require</span> <span class="hljs-string">'mkdirp'</span>
|
||||
{spawn, exec} = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
||||
{EventEmitter} = <span class="hljs-built_in">require</span> <span class="hljs-string">'events'</span>
|
||||
|
||||
useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs-string">'\\'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -126,21 +142,16 @@ interactive REPL.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>External dependencies.
|
||||
</p>
|
||||
<p>Allow CoffeeScript to emit Node.js events.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>fs = require <span class="string">'fs'</span>
|
||||
path = require <span class="string">'path'</span>
|
||||
helpers = require <span class="string">'./helpers'</span>
|
||||
optparse = require <span class="string">'./optparse'</span>
|
||||
CoffeeScript = require <span class="string">'./coffee-script'</span>
|
||||
{spawn, exec} = require <span class="string">'child_process'</span>
|
||||
{EventEmitter} = require <span class="string">'events'</span>
|
||||
<div class="content"><div class='highlight'><pre>helpers.extend CoffeeScript, <span class="hljs-keyword">new</span> EventEmitter
|
||||
|
||||
exists = fs.exists <span class="keyword">or</span> path.exists
|
||||
useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'\\'</span></pre></div></div>
|
||||
<span class="hljs-function"><span class="hljs-title">printLine</span> = <span class="hljs-params">(line)</span> -></span> process.stdout.write line + <span class="hljs-string">'\n'</span>
|
||||
<span class="hljs-function"><span class="hljs-title">printWarn</span> = <span class="hljs-params">(line)</span> -></span> process.stderr.write line + <span class="hljs-string">'\n'</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">hidden</span> = <span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/^\.|~$/</span>.test file</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -151,17 +162,15 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Allow CoffeeScript to emit Node.js events.
|
||||
</p>
|
||||
<p>The help banner that is printed in conjunction with <code>-h</code>/<code>--help</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>helpers.extend CoffeeScript, <span class="keyword">new</span> EventEmitter
|
||||
<div class="content"><div class='highlight'><pre>BANNER = <span class="hljs-string">'''
|
||||
Usage: coffee [options] path/to/script.coffee -- [args]
|
||||
|
||||
<span class="function"><span class="title">printLine</span></span> = (line) -> process.stdout.write line + <span class="string">'\n'</span>
|
||||
<span class="function"><span class="title">printWarn</span></span> = (line) -> process.stderr.write line + <span class="string">'\n'</span>
|
||||
|
||||
<span class="function"><span class="title">hidden</span></span> = (file) -> <span class="regexp">/^\.|~$/</span>.test file</pre></div></div>
|
||||
If called without options, `coffee` will run your script.
|
||||
'''</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -172,16 +181,29 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>The help banner that is printed when <code>coffee</code> is called without arguments.
|
||||
</p>
|
||||
<p>The list of all the valid option flags that <code>coffee</code> knows how to handle.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>BANNER = '''
|
||||
Usage: coffee [options] path/to/script.coffee -- [args]
|
||||
|
||||
If called without options, `coffee` will run your script.
|
||||
'''</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>SWITCHES = [
|
||||
[<span class="hljs-string">'-b'</span>, <span class="hljs-string">'--bare'</span>, <span class="hljs-string">'compile without a top-level function wrapper'</span>]
|
||||
[<span class="hljs-string">'-c'</span>, <span class="hljs-string">'--compile'</span>, <span class="hljs-string">'compile to JavaScript and save as .js files'</span>]
|
||||
[<span class="hljs-string">'-e'</span>, <span class="hljs-string">'--eval'</span>, <span class="hljs-string">'pass a string from the command line as input'</span>]
|
||||
[<span class="hljs-string">'-h'</span>, <span class="hljs-string">'--help'</span>, <span class="hljs-string">'display this help message'</span>]
|
||||
[<span class="hljs-string">'-i'</span>, <span class="hljs-string">'--interactive'</span>, <span class="hljs-string">'run an interactive CoffeeScript REPL'</span>]
|
||||
[<span class="hljs-string">'-j'</span>, <span class="hljs-string">'--join [FILE]'</span>, <span class="hljs-string">'concatenate the source CoffeeScript before compiling'</span>]
|
||||
[<span class="hljs-string">'-m'</span>, <span class="hljs-string">'--map'</span>, <span class="hljs-string">'generate source map and save as .map files'</span>]
|
||||
[<span class="hljs-string">'-n'</span>, <span class="hljs-string">'--nodes'</span>, <span class="hljs-string">'print out the parse tree that the parser produces'</span>]
|
||||
[ <span class="hljs-string">'--nodejs [ARGS]'</span>, <span class="hljs-string">'pass options directly to the "node" binary'</span>]
|
||||
[ <span class="hljs-string">'--no-header'</span>, <span class="hljs-string">'suppress the "Generated by" header'</span>]
|
||||
[<span class="hljs-string">'-o'</span>, <span class="hljs-string">'--output [DIR]'</span>, <span class="hljs-string">'set the output directory for compiled JavaScript'</span>]
|
||||
[<span class="hljs-string">'-p'</span>, <span class="hljs-string">'--print'</span>, <span class="hljs-string">'print out the compiled JavaScript'</span>]
|
||||
[<span class="hljs-string">'-s'</span>, <span class="hljs-string">'--stdio'</span>, <span class="hljs-string">'listen for and compile scripts over stdio'</span>]
|
||||
[<span class="hljs-string">'-l'</span>, <span class="hljs-string">'--literate'</span>, <span class="hljs-string">'treat stdio as literate style coffee-script'</span>]
|
||||
[<span class="hljs-string">'-t'</span>, <span class="hljs-string">'--tokens'</span>, <span class="hljs-string">'print out the tokens that the lexer/rewriter produce'</span>]
|
||||
[<span class="hljs-string">'-v'</span>, <span class="hljs-string">'--version'</span>, <span class="hljs-string">'display the version number'</span>]
|
||||
[<span class="hljs-string">'-w'</span>, <span class="hljs-string">'--watch'</span>, <span class="hljs-string">'watch scripts for changes and rerun commands'</span>]
|
||||
]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -192,29 +214,16 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>The list of all the valid option flags that <code>coffee</code> knows how to handle.
|
||||
</p>
|
||||
<p>Top-level objects shared by all the functions.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>SWITCHES = [
|
||||
[<span class="string">'-b'</span>, <span class="string">'--bare'</span>, <span class="string">'compile without a top-level function wrapper'</span>]
|
||||
[<span class="string">'-c'</span>, <span class="string">'--compile'</span>, <span class="string">'compile to JavaScript and save as .js files'</span>]
|
||||
[<span class="string">'-e'</span>, <span class="string">'--eval'</span>, <span class="string">'pass a string from the command line as input'</span>]
|
||||
[<span class="string">'-h'</span>, <span class="string">'--help'</span>, <span class="string">'display this help message'</span>]
|
||||
[<span class="string">'-i'</span>, <span class="string">'--interactive'</span>, <span class="string">'run an interactive CoffeeScript REPL'</span>]
|
||||
[<span class="string">'-j'</span>, <span class="string">'--join [FILE]'</span>, <span class="string">'concatenate the source CoffeeScript before compiling'</span>]
|
||||
[<span class="string">'-m'</span>, <span class="string">'--map'</span>, <span class="string">'generate source map and save as .map files'</span>]
|
||||
[<span class="string">'-n'</span>, <span class="string">'--nodes'</span>, <span class="string">'print out the parse tree that the parser produces'</span>]
|
||||
[ <span class="string">'--nodejs [ARGS]'</span>, <span class="string">'pass options directly to the "node" binary'</span>]
|
||||
[<span class="string">'-o'</span>, <span class="string">'--output [DIR]'</span>, <span class="string">'set the output directory for compiled JavaScript'</span>]
|
||||
[<span class="string">'-p'</span>, <span class="string">'--print'</span>, <span class="string">'print out the compiled JavaScript'</span>]
|
||||
[<span class="string">'-s'</span>, <span class="string">'--stdio'</span>, <span class="string">'listen for and compile scripts over stdio'</span>]
|
||||
[<span class="string">'-l'</span>, <span class="string">'--literate'</span>, <span class="string">'treat stdio as literate style coffee-script'</span>]
|
||||
[<span class="string">'-t'</span>, <span class="string">'--tokens'</span>, <span class="string">'print out the tokens that the lexer/rewriter produce'</span>]
|
||||
[<span class="string">'-v'</span>, <span class="string">'--version'</span>, <span class="string">'display the version number'</span>]
|
||||
[<span class="string">'-w'</span>, <span class="string">'--watch'</span>, <span class="string">'watch scripts for changes and rerun commands'</span>]
|
||||
]</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>opts = {}
|
||||
sources = []
|
||||
sourceCode = []
|
||||
notSources = {}
|
||||
watchedDirs = {}
|
||||
optionParser = <span class="hljs-literal">null</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -225,17 +234,14 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Top-level objects shared by all the functions.
|
||||
</p>
|
||||
<p>Run <code>coffee</code> by parsing passed options and determining what action to take.
|
||||
Many flags cause us to divert before compiling anything. Flags passed after
|
||||
<code>--</code> will be passed verbatim to your script as arguments in <code>process.argv</code></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>opts = {}
|
||||
sources = []
|
||||
sourceCode = []
|
||||
notSources = {}
|
||||
watchers = {}
|
||||
optionParser = <span class="literal">null</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = -></span>
|
||||
parseOptions()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -246,29 +252,29 @@ optionParser = <span class="literal">null</span></pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Run <code>coffee</code> by parsing passed options and determining what action to take.
|
||||
Many flags cause us to divert before compiling anything. Flags passed after
|
||||
<code>--</code> will be passed verbatim to your script as arguments in <code>process.argv</code>
|
||||
</p>
|
||||
<p>Make the REPL <em>CLI</em> use the global context so as to (a) be consistent with the
|
||||
<code>node</code> REPL CLI and, therefore, (b) make packages that modify native prototypes
|
||||
(such as 'colors' and 'sugar') work as expected.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">run</span></span> = ->
|
||||
parseOptions()
|
||||
<span class="keyword">return</span> forkNode() <span class="keyword">if</span> opts.nodejs
|
||||
<span class="keyword">return</span> usage() <span class="keyword">if</span> opts.help
|
||||
<span class="keyword">return</span> version() <span class="keyword">if</span> opts.version
|
||||
<span class="keyword">return</span> require(<span class="string">'./repl'</span>).start() <span class="keyword">if</span> opts.interactive
|
||||
<span class="keyword">if</span> opts.watch <span class="keyword">and</span> <span class="keyword">not</span> fs.watch
|
||||
<span class="keyword">return</span> printWarn <span class="string">"The --watch feature depends on Node v0.6.0+. You are running <span class="subst">#{process.version}</span>."</span>
|
||||
<span class="keyword">return</span> compileStdio() <span class="keyword">if</span> opts.stdio
|
||||
<span class="keyword">return</span> compileScript <span class="literal">null</span>, sources[<span class="number">0</span>] <span class="keyword">if</span> opts.eval
|
||||
<span class="keyword">return</span> require(<span class="string">'./repl'</span>).start() <span class="keyword">unless</span> sources.length
|
||||
literals = <span class="keyword">if</span> opts.run <span class="keyword">then</span> sources.splice <span class="number">1</span> <span class="keyword">else</span> []
|
||||
process.argv = process.argv[<span class="number">0.</span><span class="number">.1</span>].concat literals
|
||||
process.argv[<span class="number">0</span>] = <span class="string">'coffee'</span>
|
||||
<span class="keyword">for</span> source <span class="keyword">in</span> sources
|
||||
compilePath source, <span class="literal">yes</span>, path.normalize source</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> replCliOpts = <span class="hljs-attribute">useGlobal</span>: <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-keyword">return</span> forkNode() <span class="hljs-keyword">if</span> opts.nodejs
|
||||
<span class="hljs-keyword">return</span> usage() <span class="hljs-keyword">if</span> opts.help
|
||||
<span class="hljs-keyword">return</span> version() <span class="hljs-keyword">if</span> opts.version
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">if</span> opts.interactive
|
||||
<span class="hljs-keyword">return</span> compileStdio() <span class="hljs-keyword">if</span> opts.stdio
|
||||
<span class="hljs-keyword">return</span> compileScript <span class="hljs-literal">null</span>, opts.arguments[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> opts.eval
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">unless</span> opts.arguments.length
|
||||
literals = <span class="hljs-keyword">if</span> opts.run <span class="hljs-keyword">then</span> opts.arguments.splice <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> []
|
||||
process.argv = process.argv[<span class="hljs-number">0.</span><span class="hljs-number">.1</span>].concat literals
|
||||
process.argv[<span class="hljs-number">0</span>] = <span class="hljs-string">'coffee'</span>
|
||||
|
||||
opts.output = path.resolve opts.output <span class="hljs-keyword">if</span> opts.output
|
||||
opts.join = path.resolve opts.join <span class="hljs-keyword">if</span> opts.join
|
||||
<span class="hljs-keyword">for</span> source <span class="hljs-keyword">in</span> opts.arguments
|
||||
source = path.resolve source
|
||||
compilePath source, <span class="hljs-literal">yes</span>, source</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -281,37 +287,57 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||
</div>
|
||||
<p>Compile a path, which could be a script or a directory. If a directory
|
||||
is passed, recursively compile all '.coffee', '.litcoffee', and '.coffee.md'
|
||||
extension source files in it and all subdirectories.
|
||||
</p>
|
||||
extension source files in it and all subdirectories.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compilePath</span></span> = (source, topLevel, base) ->
|
||||
fs.stat source, (err, stats) ->
|
||||
<span class="keyword">throw</span> err <span class="keyword">if</span> err <span class="keyword">and</span> err.code <span class="keyword">isnt</span> <span class="string">'ENOENT'</span>
|
||||
<span class="keyword">if</span> err?.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
console.error <span class="string">"File not found: <span class="subst">#{source}</span>"</span>
|
||||
process.exit <span class="number">1</span>
|
||||
<span class="keyword">if</span> stats.isDirectory() <span class="keyword">and</span> path.dirname(source) <span class="keyword">isnt</span> <span class="string">'node_modules'</span>
|
||||
watchDir source, base <span class="keyword">if</span> opts.watch
|
||||
fs.readdir source, (err, files) ->
|
||||
<span class="keyword">throw</span> err <span class="keyword">if</span> err <span class="keyword">and</span> err.code <span class="keyword">isnt</span> <span class="string">'ENOENT'</span>
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> err?.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
index = sources.indexOf source
|
||||
files = files.filter (file) -> <span class="keyword">not</span> hidden file
|
||||
sources[index..index] = (path.join source, file <span class="keyword">for</span> file <span class="keyword">in</span> files)
|
||||
sourceCode[index..index] = files.map -> <span class="literal">null</span>
|
||||
files.forEach (file) ->
|
||||
compilePath (path.join source, file), <span class="literal">no</span>, base
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> topLevel <span class="keyword">or</span> helpers.isCoffee source
|
||||
watch source, base <span class="keyword">if</span> opts.watch
|
||||
fs.readFile source, (err, code) ->
|
||||
<span class="keyword">throw</span> err <span class="keyword">if</span> err <span class="keyword">and</span> err.code <span class="keyword">isnt</span> <span class="string">'ENOENT'</span>
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> err?.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
compileScript(source, code.toString(), base)
|
||||
<span class="keyword">else</span>
|
||||
notSources[source] = <span class="literal">yes</span>
|
||||
removeSource source, base</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compilePath</span> = <span class="hljs-params">(source, topLevel, base)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> source <span class="hljs-keyword">in</span> sources <span class="hljs-keyword">or</span>
|
||||
watchedDirs[source] <span class="hljs-keyword">or</span>
|
||||
<span class="hljs-keyword">not</span> topLevel <span class="hljs-keyword">and</span> (notSources[source] <span class="hljs-keyword">or</span> hidden source)
|
||||
<span class="hljs-keyword">try</span>
|
||||
stats = fs.statSync source
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"File not found: <span class="hljs-subst">#{source}</span>"</span>
|
||||
process.exit <span class="hljs-number">1</span>
|
||||
<span class="hljs-keyword">throw</span> err
|
||||
<span class="hljs-keyword">if</span> stats.isDirectory()
|
||||
<span class="hljs-keyword">if</span> path.basename(source) <span class="hljs-keyword">is</span> <span class="hljs-string">'node_modules'</span>
|
||||
notSources[source] = <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-keyword">return</span>
|
||||
<span class="hljs-keyword">if</span> opts.run
|
||||
compilePath findDirectoryIndex(source), topLevel, base
|
||||
<span class="hljs-keyword">return</span>
|
||||
watchDir source, base <span class="hljs-keyword">if</span> opts.watch
|
||||
<span class="hljs-keyword">try</span>
|
||||
files = fs.readdirSync source
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
||||
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
||||
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> topLevel <span class="hljs-keyword">or</span> helpers.isCoffee source
|
||||
sources.push source
|
||||
sourceCode.push <span class="hljs-literal">null</span>
|
||||
<span class="hljs-keyword">delete</span> notSources[source]
|
||||
watch source, base <span class="hljs-keyword">if</span> opts.watch
|
||||
<span class="hljs-keyword">try</span>
|
||||
code = fs.readFileSync source
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
||||
compileScript(source, code.toString(), base)
|
||||
<span class="hljs-keyword">else</span>
|
||||
notSources[source] = <span class="hljs-literal">yes</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">findDirectoryIndex</span> = <span class="hljs-params">(source)</span> -></span>
|
||||
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS
|
||||
index = path.join source, <span class="hljs-string">"index<span class="hljs-subst">#{ext}</span>"</span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
<span class="hljs-keyword">return</span> index <span class="hljs-keyword">if</span> (fs.statSync index).isFile()
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Missing index.coffee or index.litcoffee in <span class="hljs-subst">#{source}</span>"</span>
|
||||
process.exit <span class="hljs-number">1</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -324,46 +350,48 @@ extension source files in it and all subdirectories.
|
|||
</div>
|
||||
<p>Compile a single source script, containing the given code, according to the
|
||||
requested options. If evaluating the script directly sets <code>__filename</code>,
|
||||
<code>__dirname</code> and <code>module.filename</code> to be correct relative to the script's path.
|
||||
</p>
|
||||
<code>__dirname</code> and <code>module.filename</code> to be correct relative to the script's path.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compileScript</span></span> = (file, input, base=<span class="literal">null</span>) ->
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileScript</span> = <span class="hljs-params">(file, input, base = <span class="hljs-literal">null</span>)</span> -></span>
|
||||
o = opts
|
||||
options = compileOptions file, base
|
||||
<span class="keyword">try</span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
t = task = {file, input, options}
|
||||
CoffeeScript.emit <span class="string">'compile'</span>, task
|
||||
<span class="keyword">if</span> o.tokens <span class="keyword">then</span> printTokens CoffeeScript.tokens t.input, t.options
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> o.nodes <span class="keyword">then</span> printLine CoffeeScript.nodes(t.input, t.options).toString().trim()
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> o.run <span class="keyword">then</span> CoffeeScript.run t.input, t.options
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> o.join <span class="keyword">and</span> t.file <span class="keyword">isnt</span> o.join
|
||||
t.input = helpers.invertLiterate t.input <span class="keyword">if</span> helpers.isLiterate file
|
||||
CoffeeScript.emit <span class="hljs-string">'compile'</span>, task
|
||||
<span class="hljs-keyword">if</span> o.tokens
|
||||
printTokens CoffeeScript.tokens t.input, t.options
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> o.nodes
|
||||
printLine CoffeeScript.nodes(t.input, t.options).toString().trim()
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> o.run
|
||||
CoffeeScript.register()
|
||||
CoffeeScript.run t.input, t.options
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> o.join <span class="hljs-keyword">and</span> t.file <span class="hljs-keyword">isnt</span> o.join
|
||||
t.input = helpers.invertLiterate t.input <span class="hljs-keyword">if</span> helpers.isLiterate file
|
||||
sourceCode[sources.indexOf(t.file)] = t.input
|
||||
compileJoin()
|
||||
<span class="keyword">else</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
compiled = CoffeeScript.compile t.input, t.options
|
||||
t.output = compiled
|
||||
<span class="keyword">if</span> o.map
|
||||
<span class="hljs-keyword">if</span> o.map
|
||||
t.output = compiled.js
|
||||
t.sourceMap = compiled.v3SourceMap
|
||||
|
||||
CoffeeScript.emit <span class="string">'success'</span>, task
|
||||
<span class="keyword">if</span> o.print
|
||||
CoffeeScript.emit <span class="hljs-string">'success'</span>, task
|
||||
<span class="hljs-keyword">if</span> o.<span class="hljs-built_in">print</span>
|
||||
printLine t.output.trim()
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> o.compile <span class="keyword">or</span> o.map
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> o.compile <span class="hljs-keyword">or</span> o.map
|
||||
writeJs base, t.file, t.output, options.jsPath, t.sourceMap
|
||||
<span class="keyword">catch</span> err
|
||||
CoffeeScript.emit <span class="string">'failure'</span>, err, task
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> CoffeeScript.listeners(<span class="string">'failure'</span>).length
|
||||
useColors = process.stdout.isTTY <span class="keyword">and</span> <span class="keyword">not</span> process.env.NODE_DISABLE_COLORS
|
||||
message = helpers.prettyErrorMessage err, file <span class="keyword">or</span> <span class="string">'[stdin]'</span>, input, useColors
|
||||
<span class="keyword">if</span> o.watch
|
||||
printLine message + <span class="string">'\x07'</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
CoffeeScript.emit <span class="hljs-string">'failure'</span>, err, task
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> CoffeeScript.listeners(<span class="hljs-string">'failure'</span>).length
|
||||
message = err.stack <span class="hljs-keyword">or</span> <span class="hljs-string">"<span class="hljs-subst">#{err}</span>"</span>
|
||||
<span class="hljs-keyword">if</span> o.watch
|
||||
printLine message + <span class="hljs-string">'\x07'</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
printWarn message
|
||||
process.exit <span class="number">1</span></pre></div></div>
|
||||
process.exit <span class="hljs-number">1</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -375,18 +403,17 @@ requested options. If evaluating the script directly sets <code>__filename</code
|
|||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
|
||||
and write them back to <strong>stdout</strong>.
|
||||
</p>
|
||||
and write them back to <strong>stdout</strong>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compileStdio</span></span> = ->
|
||||
code = <span class="string">''</span>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -></span>
|
||||
code = <span class="hljs-string">''</span>
|
||||
stdin = process.openStdin()
|
||||
stdin.<span class="literal">on</span> <span class="string">'data'</span>, (buffer) ->
|
||||
code += buffer.toString() <span class="keyword">if</span> buffer
|
||||
stdin.<span class="literal">on</span> <span class="string">'end'</span>, ->
|
||||
compileScript <span class="literal">null</span>, code</pre></div></div>
|
||||
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -></span>
|
||||
code += buffer.toString() <span class="hljs-keyword">if</span> buffer
|
||||
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'end'</span>,<span class="hljs-function"> -></span>
|
||||
compileScript <span class="hljs-literal">null</span>, code</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -398,18 +425,17 @@ and write them back to <strong>stdout</strong>.
|
|||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>If all of the source files are done being read, concatenate and compile
|
||||
them together.
|
||||
</p>
|
||||
them together.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>joinTimeout = <span class="literal">null</span>
|
||||
<span class="function"><span class="title">compileJoin</span></span> = ->
|
||||
<span class="keyword">return</span> <span class="keyword">unless</span> opts.join
|
||||
<span class="keyword">unless</span> sourceCode.some((code) -> code <span class="keyword">is</span> <span class="literal">null</span>)
|
||||
clearTimeout joinTimeout
|
||||
joinTimeout = wait <span class="number">100</span>, ->
|
||||
compileScript opts.join, sourceCode.join(<span class="string">'\n'</span>), opts.join</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>joinTimeout = <span class="hljs-literal">null</span>
|
||||
<span class="hljs-function"><span class="hljs-title">compileJoin</span> = -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> opts.join
|
||||
<span class="hljs-keyword">unless</span> sourceCode.some<span class="hljs-function"><span class="hljs-params">((code) -> code <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)</span>
|
||||
<span class="hljs-title">clearTimeout</span> <span class="hljs-title">joinTimeout</span>
|
||||
<span class="hljs-title">joinTimeout</span> = <span class="hljs-title">wait</span> 100, -></span>
|
||||
compileScript opts.join, sourceCode.join(<span class="hljs-string">'\n'</span>), opts.join</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -422,48 +448,54 @@ them together.
|
|||
</div>
|
||||
<p>Watch a source CoffeeScript file using <code>fs.watch</code>, recompiling it every
|
||||
time the file is updated. May be used in combination with other options,
|
||||
such as <code>--print</code>.
|
||||
</p>
|
||||
such as <code>--print</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">watch</span></span> = (source, base) ->
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">watch</span> = <span class="hljs-params">(source, base)</span> -></span>
|
||||
watcher = <span class="hljs-literal">null</span>
|
||||
prevStats = <span class="hljs-literal">null</span>
|
||||
compileTimeout = <span class="hljs-literal">null</span>
|
||||
|
||||
prevStats = <span class="literal">null</span>
|
||||
compileTimeout = <span class="literal">null</span>
|
||||
<span class="hljs-function"><span class="hljs-title">watchErr</span> = <span class="hljs-params">(err)</span> -></span>
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> source <span class="hljs-keyword">in</span> sources
|
||||
<span class="hljs-keyword">try</span>
|
||||
rewatch()
|
||||
compile()
|
||||
<span class="hljs-keyword">catch</span>
|
||||
removeSource source, base
|
||||
compileJoin()
|
||||
|
||||
<span class="function"><span class="title">watchErr</span></span> = (e) ->
|
||||
<span class="keyword">if</span> e.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> sources.indexOf(source) <span class="keyword">is</span> -<span class="number">1</span>
|
||||
<span class="keyword">try</span>
|
||||
rewatch()
|
||||
compile()
|
||||
<span class="keyword">catch</span> e
|
||||
removeSource source, base, <span class="literal">yes</span>
|
||||
compileJoin()
|
||||
<span class="keyword">else</span> <span class="keyword">throw</span> e
|
||||
|
||||
<span class="function"><span class="title">compile</span></span> = ->
|
||||
<span class="hljs-function"><span class="hljs-title">compile</span> = -></span>
|
||||
clearTimeout compileTimeout
|
||||
compileTimeout = wait <span class="number">25</span>, ->
|
||||
fs.stat source, (err, stats) ->
|
||||
<span class="keyword">return</span> watchErr err <span class="keyword">if</span> err
|
||||
<span class="keyword">return</span> rewatch() <span class="keyword">if</span> prevStats <span class="keyword">and</span> stats.size <span class="keyword">is</span> prevStats.size <span class="keyword">and</span>
|
||||
stats.mtime.getTime() <span class="keyword">is</span> prevStats.mtime.getTime()
|
||||
compileTimeout = wait <span class="hljs-number">25</span>,<span class="hljs-function"> -></span>
|
||||
fs.stat source, <span class="hljs-function"><span class="hljs-params">(err, stats)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> watchErr err <span class="hljs-keyword">if</span> err
|
||||
<span class="hljs-keyword">return</span> rewatch() <span class="hljs-keyword">if</span> prevStats <span class="hljs-keyword">and</span>
|
||||
stats.size <span class="hljs-keyword">is</span> prevStats.size <span class="hljs-keyword">and</span>
|
||||
stats.mtime.getTime() <span class="hljs-keyword">is</span> prevStats.mtime.getTime()
|
||||
prevStats = stats
|
||||
fs.readFile source, (err, code) ->
|
||||
<span class="keyword">return</span> watchErr err <span class="keyword">if</span> err
|
||||
fs.readFile source, <span class="hljs-function"><span class="hljs-params">(err, code)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> watchErr err <span class="hljs-keyword">if</span> err
|
||||
compileScript(source, code.toString(), base)
|
||||
rewatch()
|
||||
|
||||
<span class="keyword">try</span>
|
||||
watcher = fs.watch source, compile
|
||||
<span class="keyword">catch</span> e
|
||||
watchErr e
|
||||
<span class="hljs-function"><span class="hljs-title">startWatcher</span> = -></span>
|
||||
watcher = fs.watch source
|
||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, compile
|
||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
||||
removeSource source, base
|
||||
|
||||
<span class="function"><span class="title">rewatch</span></span> = ->
|
||||
<span class="hljs-function"><span class="hljs-title">rewatch</span> = -></span>
|
||||
watcher?.close()
|
||||
watcher = fs.watch source, compile</pre></div></div>
|
||||
startWatcher()
|
||||
|
||||
<span class="hljs-keyword">try</span>
|
||||
startWatcher()
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
watchErr err</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -474,37 +506,47 @@ such as <code>--print</code>.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Watch a directory of files for new additions.
|
||||
</p>
|
||||
<p>Watch a directory of files for new additions.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">watchDir</span></span> = (source, base) ->
|
||||
readdirTimeout = <span class="literal">null</span>
|
||||
<span class="keyword">try</span>
|
||||
watcher = fs.watch source, ->
|
||||
clearTimeout readdirTimeout
|
||||
readdirTimeout = wait <span class="number">25</span>, ->
|
||||
fs.readdir source, (err, files) ->
|
||||
<span class="keyword">if</span> err
|
||||
<span class="keyword">throw</span> err <span class="keyword">unless</span> err.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
watcher.close()
|
||||
<span class="keyword">return</span> unwatchDir source, base
|
||||
<span class="keyword">for</span> file <span class="keyword">in</span> files <span class="keyword">when</span> <span class="keyword">not</span> hidden(file) <span class="keyword">and</span> <span class="keyword">not</span> notSources[file]
|
||||
file = path.join source, file
|
||||
<span class="keyword">continue</span> <span class="keyword">if</span> sources.some (s) -> s.indexOf(file) >= <span class="number">0</span>
|
||||
sources.push file
|
||||
sourceCode.push <span class="literal">null</span>
|
||||
compilePath file, <span class="literal">no</span>, base
|
||||
<span class="keyword">catch</span> e
|
||||
<span class="keyword">throw</span> e <span class="keyword">unless</span> e.code <span class="keyword">is</span> <span class="string">'ENOENT'</span>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">watchDir</span> = <span class="hljs-params">(source, base)</span> -></span>
|
||||
watcher = <span class="hljs-literal">null</span>
|
||||
readdirTimeout = <span class="hljs-literal">null</span>
|
||||
|
||||
<span class="function"><span class="title">unwatchDir</span></span> = (source, base) ->
|
||||
prevSources = sources[..]
|
||||
toRemove = (file <span class="keyword">for</span> file <span class="keyword">in</span> sources <span class="keyword">when</span> file.indexOf(source) >= <span class="number">0</span>)
|
||||
removeSource file, base, <span class="literal">yes</span> <span class="keyword">for</span> file <span class="keyword">in</span> toRemove
|
||||
<span class="keyword">return</span> <span class="keyword">unless</span> sources.some (s, i) -> prevSources[i] <span class="keyword">isnt</span> s
|
||||
compileJoin()</pre></div></div>
|
||||
<span class="hljs-function"><span class="hljs-title">startWatcher</span> = -></span>
|
||||
watcher = fs.watch source
|
||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
||||
stopWatcher()
|
||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>,<span class="hljs-function"> -></span>
|
||||
clearTimeout readdirTimeout
|
||||
readdirTimeout = wait <span class="hljs-number">25</span>,<span class="hljs-function"> -></span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
files = fs.readdirSync source
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||
<span class="hljs-keyword">return</span> stopWatcher()
|
||||
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
||||
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">stopWatcher</span> = -></span>
|
||||
watcher.close()
|
||||
removeSourceDir source, base
|
||||
|
||||
watchedDirs[source] = <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
startWatcher()
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">removeSourceDir</span> = <span class="hljs-params">(source, base)</span> -></span>
|
||||
<span class="hljs-keyword">delete</span> watchedDirs[source]
|
||||
sourcesChanged = <span class="hljs-literal">no</span>
|
||||
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> sources <span class="hljs-keyword">when</span> source <span class="hljs-keyword">is</span> path.dirname file
|
||||
removeSource file, base
|
||||
sourcesChanged = <span class="hljs-literal">yes</span>
|
||||
compileJoin() <span class="hljs-keyword">if</span> sourcesChanged</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -516,22 +558,24 @@ such as <code>--print</code>.
|
|||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Remove a file from our source list, and source code cache. Optionally remove
|
||||
the compiled JS version as well.
|
||||
</p>
|
||||
the compiled JS version as well.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">removeSource</span></span> = (source, base, removeJs) ->
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">removeSource</span> = <span class="hljs-params">(source, base)</span> -></span>
|
||||
index = sources.indexOf source
|
||||
sources.splice index, <span class="number">1</span>
|
||||
sourceCode.splice index, <span class="number">1</span>
|
||||
<span class="keyword">if</span> removeJs <span class="keyword">and</span> <span class="keyword">not</span> opts.join
|
||||
jsPath = outputPath source, base
|
||||
exists jsPath, (itExists) ->
|
||||
<span class="keyword">if</span> itExists
|
||||
fs.unlink jsPath, (err) ->
|
||||
<span class="keyword">throw</span> err <span class="keyword">if</span> err <span class="keyword">and</span> err.code <span class="keyword">isnt</span> <span class="string">'ENOENT'</span>
|
||||
timeLog <span class="string">"removed <span class="subst">#{source}</span>"</span></pre></div></div>
|
||||
sources.splice index, <span class="hljs-number">1</span>
|
||||
sourceCode.splice index, <span class="hljs-number">1</span>
|
||||
<span class="hljs-keyword">unless</span> opts.join
|
||||
silentUnlink outputPath source, base
|
||||
silentUnlink outputPath source, base, <span class="hljs-string">'.map'</span>
|
||||
timeLog <span class="hljs-string">"removed <span class="hljs-subst">#{source}</span>"</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">silentUnlink</span> = <span class="hljs-params">(path)</span> -></span>
|
||||
<span class="hljs-keyword">try</span>
|
||||
fs.unlinkSync path
|
||||
<span class="hljs-keyword">catch</span> err
|
||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">in</span> [<span class="hljs-string">'ENOENT'</span>, <span class="hljs-string">'EPERM'</span>]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -542,16 +586,19 @@ the compiled JS version as well.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Get the corresponding output JavaScript path for a source file.
|
||||
</p>
|
||||
<p>Get the corresponding output JavaScript path for a source file.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">outputPath</span></span> = (source, base, extension=<span class="string">".js"</span>) ->
|
||||
basename = helpers.baseFileName source, <span class="literal">yes</span>, useWinPathSep
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">outputPath</span> = <span class="hljs-params">(source, base, extension=<span class="hljs-string">".js"</span>)</span> -></span>
|
||||
basename = helpers.baseFileName source, <span class="hljs-literal">yes</span>, useWinPathSep
|
||||
srcDir = path.dirname source
|
||||
baseDir = <span class="keyword">if</span> base <span class="keyword">is</span> <span class="string">'.'</span> <span class="keyword">then</span> srcDir <span class="keyword">else</span> srcDir.substring base.length
|
||||
dir = <span class="keyword">if</span> opts.output <span class="keyword">then</span> path.join opts.output, baseDir <span class="keyword">else</span> srcDir
|
||||
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> opts.output
|
||||
dir = srcDir
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> source <span class="hljs-keyword">is</span> base
|
||||
dir = opts.output
|
||||
<span class="hljs-keyword">else</span>
|
||||
dir = path.join opts.output, path.relative base, srcDir
|
||||
path.join dir, basename + extension</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -565,33 +612,30 @@ the compiled JS version as well.
|
|||
</div>
|
||||
<p>Write out a JavaScript source file with the compiled code. By default, files
|
||||
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
|
||||
directory can be customized with <code>--output</code>.
|
||||
|
||||
</p>
|
||||
directory can be customized with <code>--output</code>.</p>
|
||||
<p>If <code>generatedSourceMap</code> is provided, this will write a <code>.map</code> file into the
|
||||
same directory as the <code>.js</code> file.
|
||||
</p>
|
||||
same directory as the <code>.js</code> file.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">writeJs</span></span> = (base, sourcePath, js, jsPath, generatedSourceMap = <span class="literal">null</span>) ->
|
||||
sourceMapPath = outputPath sourcePath, base, <span class="string">".map"</span>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -></span>
|
||||
sourceMapPath = outputPath sourcePath, base, <span class="hljs-string">".map"</span>
|
||||
jsDir = path.dirname jsPath
|
||||
<span class="function"><span class="title">compile</span></span> = ->
|
||||
<span class="keyword">if</span> opts.compile
|
||||
js = <span class="string">' '</span> <span class="keyword">if</span> js.length <= <span class="number">0</span>
|
||||
<span class="keyword">if</span> generatedSourceMap <span class="keyword">then</span> js = <span class="string">"<span class="subst">#{js}</span>\n/*\n//@ sourceMappingURL=<span class="subst">#{helpers.baseFileName sourceMapPath, <span class="literal">no</span>, useWinPathSep}</span>\n*/\n"</span>
|
||||
fs.writeFile jsPath, js, (err) ->
|
||||
<span class="keyword">if</span> err
|
||||
<span class="hljs-function"><span class="hljs-title">compile</span> = -></span>
|
||||
<span class="hljs-keyword">if</span> opts.compile
|
||||
js = <span class="hljs-string">' '</span> <span class="hljs-keyword">if</span> js.length <= <span class="hljs-number">0</span>
|
||||
<span class="hljs-keyword">if</span> generatedSourceMap <span class="hljs-keyword">then</span> js = <span class="hljs-string">"<span class="hljs-subst">#{js}</span>\n//# sourceMappingURL=<span class="hljs-subst">#{helpers.baseFileName sourceMapPath, <span class="hljs-literal">no</span>, useWinPathSep}</span>\n"</span>
|
||||
fs.writeFile jsPath, js, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> err
|
||||
printLine err.message
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> opts.compile <span class="keyword">and</span> opts.watch
|
||||
timeLog <span class="string">"compiled <span class="subst">#{sourcePath}</span>"</span>
|
||||
<span class="keyword">if</span> generatedSourceMap
|
||||
fs.writeFile sourceMapPath, generatedSourceMap, (err) ->
|
||||
<span class="keyword">if</span> err
|
||||
printLine <span class="string">"Could not write source map: <span class="subst">#{err.message}</span>"</span>
|
||||
exists jsDir, (itExists) ->
|
||||
<span class="keyword">if</span> itExists <span class="keyword">then</span> compile() <span class="keyword">else</span> exec <span class="string">"mkdir -p <span class="subst">#{jsDir}</span>"</span>, compile</pre></div></div>
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.compile <span class="hljs-keyword">and</span> opts.watch
|
||||
timeLog <span class="hljs-string">"compiled <span class="hljs-subst">#{sourcePath}</span>"</span>
|
||||
<span class="hljs-keyword">if</span> generatedSourceMap
|
||||
fs.writeFile sourceMapPath, generatedSourceMap, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> err
|
||||
printLine <span class="hljs-string">"Could not write source map: <span class="hljs-subst">#{err.message}</span>"</span>
|
||||
fs.exists jsDir, <span class="hljs-function"><span class="hljs-params">(itExists)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> itExists <span class="hljs-keyword">then</span> compile() <span class="hljs-keyword">else</span> mkdirp jsDir, compile</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -602,12 +646,11 @@ same directory as the <code>.js</code> file.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>Convenience for cleaner setTimeouts.
|
||||
</p>
|
||||
<p>Convenience for cleaner setTimeouts.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">wait</span></span> = (milliseconds, func) -> setTimeout func, milliseconds</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">wait</span> = <span class="hljs-params">(milliseconds, func)</span> -></span> setTimeout func, milliseconds</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -618,13 +661,12 @@ same directory as the <code>.js</code> file.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>When watching scripts, it's useful to log changes with the timestamp.
|
||||
</p>
|
||||
<p>When watching scripts, it's useful to log changes with the timestamp.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">timeLog</span></span> = (message) ->
|
||||
console.log <span class="string">"<span class="subst">#{(<span class="keyword">new</span> Date).toLocaleTimeString()}</span> - <span class="subst">#{message}</span>"</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">timeLog</span> = <span class="hljs-params">(message)</span> -></span>
|
||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"<span class="hljs-subst">#{(<span class="hljs-keyword">new</span> Date).toLocaleTimeString()}</span> - <span class="hljs-subst">#{message}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -635,17 +677,16 @@ same directory as the <code>.js</code> file.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>Pretty-print a stream of tokens, sans location data.
|
||||
</p>
|
||||
<p>Pretty-print a stream of tokens, sans location data.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">printTokens</span></span> = (tokens) ->
|
||||
strings = <span class="keyword">for</span> token <span class="keyword">in</span> tokens
|
||||
tag = token[<span class="number">0</span>]
|
||||
value = token[<span class="number">1</span>].toString().replace(<span class="regexp">/\n/</span>, <span class="string">'\\n'</span>)
|
||||
<span class="string">"[<span class="subst">#{tag}</span> <span class="subst">#{value}</span>]"</span>
|
||||
printLine strings.join(<span class="string">' '</span>)</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTokens</span> = <span class="hljs-params">(tokens)</span> -></span>
|
||||
strings = <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens
|
||||
tag = token[<span class="hljs-number">0</span>]
|
||||
value = token[<span class="hljs-number">1</span>].toString().replace(<span class="hljs-regexp">/\n/</span>, <span class="hljs-string">'\\n'</span>)
|
||||
<span class="hljs-string">"[<span class="hljs-subst">#{tag}</span> <span class="hljs-subst">#{value}</span>]"</span>
|
||||
printLine strings.join(<span class="hljs-string">' '</span>)</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -657,20 +698,16 @@ same directory as the <code>.js</code> file.
|
|||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
|
||||
<code>process.argv</code> that are specified in <code>SWITCHES</code>.
|
||||
</p>
|
||||
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">parseOptions</span></span> = ->
|
||||
optionParser = <span class="keyword">new</span> optparse.OptionParser SWITCHES, BANNER
|
||||
o = opts = optionParser.parse process.argv[<span class="number">2.</span>.]
|
||||
o.compile <span class="keyword">or</span>= !!o.output
|
||||
o.run = <span class="keyword">not</span> (o.compile <span class="keyword">or</span> o.print <span class="keyword">or</span> o.map)
|
||||
o.print = !! (o.print <span class="keyword">or</span> (o.eval <span class="keyword">or</span> o.stdio <span class="keyword">and</span> o.compile))
|
||||
sources = o.arguments
|
||||
sourceCode[i] = <span class="literal">null</span> <span class="keyword">for</span> source, i <span class="keyword">in</span> sources
|
||||
<span class="keyword">return</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">parseOptions</span> = -></span>
|
||||
optionParser = <span class="hljs-keyword">new</span> optparse.OptionParser SWITCHES, BANNER
|
||||
o = opts = optionParser.parse process.argv[<span class="hljs-number">2.</span>.]
|
||||
o.compile <span class="hljs-keyword">or</span>= !!o.output
|
||||
o.run = <span class="hljs-keyword">not</span> (o.compile <span class="hljs-keyword">or</span> o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> o.map)
|
||||
o.<span class="hljs-built_in">print</span> = !! (o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> (o.eval <span class="hljs-keyword">or</span> o.stdio <span class="hljs-keyword">and</span> o.compile))</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -681,35 +718,34 @@ same directory as the <code>.js</code> file.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>The compile-time options to pass to the CoffeeScript compiler.
|
||||
</p>
|
||||
<p>The compile-time options to pass to the CoffeeScript compiler.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compileOptions</span></span> = (filename, base) ->
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileOptions</span> = <span class="hljs-params">(filename, base)</span> -></span>
|
||||
answer = {
|
||||
filename
|
||||
literate: opts.literate <span class="keyword">or</span> helpers.isLiterate(filename)
|
||||
bare: opts.bare
|
||||
header: opts.compile
|
||||
sourceMap: opts.map
|
||||
<span class="hljs-attribute">literate</span>: opts.literate <span class="hljs-keyword">or</span> helpers.isLiterate(filename)
|
||||
<span class="hljs-attribute">bare</span>: opts.bare
|
||||
<span class="hljs-attribute">header</span>: opts.compile <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> opts[<span class="hljs-string">'no-header'</span>]
|
||||
<span class="hljs-attribute">sourceMap</span>: opts.map
|
||||
}
|
||||
<span class="keyword">if</span> filename
|
||||
<span class="keyword">if</span> base
|
||||
<span class="hljs-keyword">if</span> filename
|
||||
<span class="hljs-keyword">if</span> base
|
||||
cwd = process.cwd()
|
||||
jsPath = outputPath filename, base
|
||||
jsDir = path.dirname jsPath
|
||||
answer = helpers.merge answer, {
|
||||
jsPath
|
||||
sourceRoot: path.relative jsDir, cwd
|
||||
sourceFiles: [path.relative cwd, filename]
|
||||
generatedFile: helpers.baseFileName(jsPath, <span class="literal">no</span>, useWinPathSep)
|
||||
<span class="hljs-attribute">sourceRoot</span>: path.relative jsDir, cwd
|
||||
<span class="hljs-attribute">sourceFiles</span>: [path.relative cwd, filename]
|
||||
<span class="hljs-attribute">generatedFile</span>: helpers.baseFileName(jsPath, <span class="hljs-literal">no</span>, useWinPathSep)
|
||||
}
|
||||
<span class="keyword">else</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
answer = helpers.merge answer,
|
||||
sourceRoot: <span class="string">""</span>
|
||||
sourceFiles: [helpers.baseFileName filename, <span class="literal">no</span>, useWinPathSep]
|
||||
generatedFile: helpers.baseFileName(filename, <span class="literal">yes</span>, useWinPathSep) + <span class="string">".js"</span>
|
||||
<span class="hljs-attribute">sourceRoot</span>: <span class="hljs-string">""</span>
|
||||
<span class="hljs-attribute">sourceFiles</span>: [helpers.baseFileName filename, <span class="hljs-literal">no</span>, useWinPathSep]
|
||||
<span class="hljs-attribute">generatedFile</span>: helpers.baseFileName(filename, <span class="hljs-literal">yes</span>, useWinPathSep) + <span class="hljs-string">".js"</span>
|
||||
answer</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
@ -722,19 +758,19 @@ same directory as the <code>.js</code> file.
|
|||
<a class="pilcrow" href="#section-22">¶</a>
|
||||
</div>
|
||||
<p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
|
||||
the <code>node</code> binary, preserving the other options.
|
||||
</p>
|
||||
the <code>node</code> binary, preserving the other options.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">forkNode</span></span> = ->
|
||||
nodeArgs = opts.nodejs.split <span class="regexp">/\s+/</span>
|
||||
args = process.argv[<span class="number">1.</span>.]
|
||||
args.splice args.indexOf(<span class="string">'--nodejs'</span>), <span class="number">2</span>
|
||||
spawn process.execPath, nodeArgs.concat(args),
|
||||
cwd: process.cwd()
|
||||
env: process.env
|
||||
customFds: [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">forkNode</span> = -></span>
|
||||
nodeArgs = opts.nodejs.split <span class="hljs-regexp">/\s+/</span>
|
||||
args = process.argv[<span class="hljs-number">1.</span>.]
|
||||
args.splice args.indexOf(<span class="hljs-string">'--nodejs'</span>), <span class="hljs-number">2</span>
|
||||
p = spawn process.execPath, nodeArgs.concat(args),
|
||||
<span class="hljs-attribute">cwd</span>: process.cwd()
|
||||
<span class="hljs-attribute">env</span>: process.env
|
||||
<span class="hljs-attribute">customFds</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
|
||||
p.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span> process.exit code</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -746,13 +782,12 @@ the <code>node</code> binary, preserving the other options.
|
|||
<a class="pilcrow" href="#section-23">¶</a>
|
||||
</div>
|
||||
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
|
||||
shown.
|
||||
</p>
|
||||
shown.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">usage</span></span> = ->
|
||||
printLine (<span class="keyword">new</span> optparse.OptionParser SWITCHES, BANNER).help()</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">usage</span> = -></span>
|
||||
printLine (<span class="hljs-keyword">new</span> optparse.OptionParser SWITCHES, BANNER).help()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -763,13 +798,12 @@ shown.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-24">¶</a>
|
||||
</div>
|
||||
<p>Print the <code>--version</code> message and exit.
|
||||
</p>
|
||||
<p>Print the <code>--version</code> message and exit.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">version</span></span> = ->
|
||||
printLine <span class="string">"CoffeeScript version <span class="subst">#{CoffeeScript.VERSION}</span>"</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">version</span> = -></span>
|
||||
printLine <span class="hljs-string">"CoffeeScript version <span class="hljs-subst">#{CoffeeScript.VERSION}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -51,17 +51,9 @@ b, strong {
|
|||
font-family: "aller-bold";
|
||||
}
|
||||
|
||||
p {
|
||||
p, ul, ol {
|
||||
margin: 15px 0 0px;
|
||||
}
|
||||
.annotation ul, .annotation ol {
|
||||
margin: 25px 0;
|
||||
}
|
||||
.annotation ul li, .annotation ol li {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #112233;
|
||||
|
@ -399,8 +391,7 @@ pre .css .rule .keyword,
|
|||
pre .winutils,
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .subst,
|
||||
pre .reserved {
|
||||
pre .subst {
|
||||
color: #954121;
|
||||
/*font-weight: bold*/
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -110,11 +115,14 @@
|
|||
</div>
|
||||
<p>This file contains the common helper functions that we'd like to share among
|
||||
the <strong>Lexer</strong>, <strong>Rewriter</strong>, and the <strong>Nodes</strong>. Merge objects, flatten
|
||||
arrays, count characters, that sort of thing.
|
||||
</p>
|
||||
arrays, count characters, that sort of thing.</p>
|
||||
<p>Peek at the beginning of a given string to see if it matches a sequence.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">starts</span> = <span class="hljs-params">(string, literal, start)</span> -></span>
|
||||
literal <span class="hljs-keyword">is</span> string.substr start, literal.length</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -124,13 +132,13 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>Peek at the beginning of a given string to see if it matches a sequence.
|
||||
</p>
|
||||
<p>Peek at the end of a given string to see if it matches a sequence.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">starts</span></span> = (string, literal, start) ->
|
||||
literal <span class="keyword">is</span> string.substr start, literal.length</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">ends</span> = <span class="hljs-params">(string, literal, back)</span> -></span>
|
||||
len = literal.length
|
||||
literal <span class="hljs-keyword">is</span> string.substr string.length - len - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>), len</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -141,14 +149,11 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Peek at the end of a given string to see if it matches a sequence.
|
||||
</p>
|
||||
<p>Repeat a string <code>n</code> times.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">ends</span></span> = (string, literal, back) ->
|
||||
len = literal.length
|
||||
literal <span class="keyword">is</span> string.substr string.length - len - (back <span class="keyword">or</span> <span class="number">0</span>), len</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.repeat = <span class="hljs-function"><span class="hljs-title">repeat</span> = <span class="hljs-params">(str, n)</span> -></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -159,12 +164,16 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Repeat a string <code>n</code> times.
|
||||
</p>
|
||||
<p>Use clever algorithm to have O(log(n)) string concatenation operations.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.repeat = <span class="function"><span class="title">repeat</span></span> = (str, n) -></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> res = <span class="hljs-string">''</span>
|
||||
<span class="hljs-keyword">while</span> n > <span class="hljs-number">0</span>
|
||||
res += str <span class="hljs-keyword">if</span> n & <span class="hljs-number">1</span>
|
||||
n >>>= <span class="hljs-number">1</span>
|
||||
str += str
|
||||
res</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -175,17 +184,12 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Use clever algorithm to have O(log(n)) string concatenation operations.
|
||||
</p>
|
||||
<p>Trim out all falsy values from an array.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> res = <span class="string">''</span>
|
||||
<span class="keyword">while</span> n > <span class="number">0</span>
|
||||
res += str <span class="keyword">if</span> n & <span class="number">1</span>
|
||||
n >>>= <span class="number">1</span>
|
||||
str += str
|
||||
res</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">compact</span> = <span class="hljs-params">(array)</span> -></span>
|
||||
item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -196,13 +200,15 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Trim out all falsy values from an array.
|
||||
</p>
|
||||
<p>Count the number of occurrences of a string in a string.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">compact</span></span> = (array) ->
|
||||
item <span class="keyword">for</span> item <span class="keyword">in</span> array <span class="keyword">when</span> item</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">count</span> = <span class="hljs-params">(string, substr)</span> -></span>
|
||||
num = pos = <span class="hljs-number">0</span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>/<span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> substr.length
|
||||
num++ <span class="hljs-keyword">while</span> pos = <span class="hljs-number">1</span> + string.indexOf substr, pos
|
||||
num</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -213,16 +219,14 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Count the number of occurrences of a string in a string.
|
||||
</p>
|
||||
<p>Merge objects, returning a fresh copy with attributes from both sides.
|
||||
Used every time <code>Base#compile</code> is called, to allow properties in the
|
||||
options hash to propagate down the tree without polluting other branches.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">count</span></span> = (string, substr) ->
|
||||
num = pos = <span class="number">0</span>
|
||||
<span class="keyword">return</span> <span class="number">1</span>/<span class="number">0</span> <span class="keyword">unless</span> substr.length
|
||||
num++ <span class="keyword">while</span> pos = <span class="number">1</span> + string.indexOf substr, pos
|
||||
num</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">merge</span> = <span class="hljs-params">(options, overrides)</span> -></span>
|
||||
extend (extend {}, options), overrides</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -233,15 +237,14 @@ arrays, count characters, that sort of thing.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Merge objects, returning a fresh copy with attributes from both sides.
|
||||
Used every time <code>Base#compile</code> is called, to allow properties in the
|
||||
options hash to propagate down the tree without polluting other branches.
|
||||
</p>
|
||||
<p>Extend a source object with the properties of another object (shallow copy).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">merge</span></span> = (options, overrides) ->
|
||||
extend (extend {}, options), overrides</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>extend = <span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">extend</span> = <span class="hljs-params">(object, properties)</span> -></span>
|
||||
<span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> properties
|
||||
object[key] = val
|
||||
object</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -252,15 +255,19 @@ options hash to propagate down the tree without polluting other branches.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Extend a source object with the properties of another object (shallow copy).
|
||||
</p>
|
||||
<p>Return a flattened version of an array.
|
||||
Handy for getting a list of <code>children</code> from the nodes.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>extend = exports.<span class="function"><span class="title">extend</span></span> = (object, properties) ->
|
||||
<span class="keyword">for</span> key, val <span class="keyword">of</span> properties
|
||||
object[key] = val
|
||||
object</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.flatten = <span class="hljs-function"><span class="hljs-title">flatten</span> = <span class="hljs-params">(array)</span> -></span>
|
||||
flattened = []
|
||||
<span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> array
|
||||
<span class="hljs-keyword">if</span> element <span class="hljs-keyword">instanceof</span> Array
|
||||
flattened = flattened.concat flatten element
|
||||
<span class="hljs-keyword">else</span>
|
||||
flattened.push element
|
||||
flattened</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -271,20 +278,15 @@ options hash to propagate down the tree without polluting other branches.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Return a flattened version of an array.
|
||||
Handy for getting a list of <code>children</code> from the nodes.
|
||||
</p>
|
||||
<p>Delete a key from an object, returning the value. Useful when a node is
|
||||
looking for a particular method in an options hash.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.flatten = <span class="function"><span class="title">flatten</span></span> = (array) ->
|
||||
flattened = []
|
||||
<span class="keyword">for</span> element <span class="keyword">in</span> array
|
||||
<span class="keyword">if</span> element <span class="keyword">instanceof</span> Array
|
||||
flattened = flattened.concat flatten element
|
||||
<span class="keyword">else</span>
|
||||
flattened.push element
|
||||
flattened</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">del</span> = <span class="hljs-params">(obj, key)</span> -></span>
|
||||
val = obj[key]
|
||||
<span class="hljs-keyword">delete</span> obj[key]
|
||||
val</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -295,16 +297,11 @@ Handy for getting a list of <code>children</code> from the nodes.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Delete a key from an object, returning the value. Useful when a node is
|
||||
looking for a particular method in an options hash.
|
||||
</p>
|
||||
<p>Gets the last item of an array(-like) object.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">del</span></span> = (obj, key) ->
|
||||
val = obj[key]
|
||||
<span class="keyword">delete</span> obj[key]
|
||||
val</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.last = <span class="hljs-function"><span class="hljs-title">last</span> = <span class="hljs-params">(array, back)</span> -></span> array[array.length - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>) - <span class="hljs-number">1</span>]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -315,12 +312,13 @@ looking for a particular method in an options hash.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>Gets the last item of an array(-like) object.
|
||||
</p>
|
||||
<p>Typical Array::some</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.last = <span class="function"><span class="title">last</span></span> = (array, back) -> array[array.length - (back <span class="keyword">or</span> <span class="number">0</span>) - <span class="number">1</span>]</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.some = <span class="hljs-attribute">Array</span>::some ? <span class="hljs-function"><span class="hljs-params">(fn)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">when</span> fn e
|
||||
<span class="hljs-literal">false</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -331,14 +329,22 @@ looking for a particular method in an options hash.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Typical Array::some
|
||||
</p>
|
||||
<p>Simple function for inverting Literate CoffeeScript code by putting the
|
||||
documentation in comments, producing a string of CoffeeScript code that
|
||||
can be compiled "normally".</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.some = Array::some ? (fn) ->
|
||||
<span class="keyword">return</span> <span class="literal">true</span> <span class="keyword">for</span> e <span class="keyword">in</span> <span class="keyword">this</span> <span class="keyword">when</span> fn e
|
||||
<span class="literal">false</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">invertLiterate</span> = <span class="hljs-params">(code)</span> -></span>
|
||||
maybe_code = <span class="hljs-literal">true</span>
|
||||
lines = <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> code.split(<span class="hljs-string">'\n'</span>)
|
||||
<span class="hljs-keyword">if</span> maybe_code <span class="hljs-keyword">and</span> <span class="hljs-regexp">/^([ ]{4}|[ ]{0,3}\t)/</span>.test line
|
||||
line
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> maybe_code = <span class="hljs-regexp">/^\s*$/</span>.test line
|
||||
line
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-string">'# '</span> + line
|
||||
lines.join <span class="hljs-string">'\n'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -349,23 +355,19 @@ looking for a particular method in an options hash.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Simple function for inverting Literate CoffeeScript code by putting the
|
||||
documentation in comments, producing a string of CoffeeScript code that
|
||||
can be compiled "normally".
|
||||
</p>
|
||||
<p>Merge two jison-style location data objects together.
|
||||
If <code>last</code> is not provided, this will simply return <code>first</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">invertLiterate</span></span> = (code) ->
|
||||
maybe_code = <span class="literal">true</span>
|
||||
lines = <span class="keyword">for</span> line <span class="keyword">in</span> code.split(<span class="string">'\n'</span>)
|
||||
<span class="keyword">if</span> maybe_code <span class="keyword">and</span> <span class="regexp">/^([ ]{4}|[ ]{0,3}\t)/</span>.test line
|
||||
line
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> maybe_code = <span class="regexp">/^\s*$/</span>.test line
|
||||
line
|
||||
<span class="keyword">else</span>
|
||||
<span class="string">'# '</span> + line
|
||||
lines.join <span class="string">'\n'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildLocationData</span> = <span class="hljs-params">(first, last)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> last
|
||||
first
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-attribute">first_line</span>: first.first_line
|
||||
<span class="hljs-attribute">first_column</span>: first.first_column
|
||||
<span class="hljs-attribute">last_line</span>: last.last_line
|
||||
<span class="hljs-attribute">last_column</span>: last.last_column</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -376,20 +378,18 @@ can be compiled "normally".
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Merge two jison-style location data objects together.
|
||||
If <code>last</code> is not provided, this will simply return <code>first</code>.
|
||||
</p>
|
||||
<p>This returns a function which takes an object as a parameter, and if that
|
||||
object is an AST node, updates that object's locationData.
|
||||
The object is returned either way.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildLocationData</span></span> = (first, last) ->
|
||||
<span class="keyword">if</span> <span class="keyword">not</span> last
|
||||
first
|
||||
<span class="keyword">else</span>
|
||||
first_line: first.first_line
|
||||
first_column: first.first_column
|
||||
last_line: last.last_line
|
||||
last_column: last.last_column</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">addLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -></span>
|
||||
<span class="hljs-function"><span class="hljs-params">(obj)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span>) <span class="hljs-keyword">and</span> (!!obj[<span class="hljs-string">'updateLocationDataIfMissing'</span>])
|
||||
obj.updateLocationDataIfMissing buildLocationData(first, last)
|
||||
|
||||
<span class="hljs-keyword">return</span> obj</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -400,19 +400,20 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>This returns a function which takes an object as a parameter, and if that
|
||||
object is an AST node, updates that object's locationData.
|
||||
The object is returned either way.
|
||||
</p>
|
||||
<p>Convert jison location data to a string.
|
||||
<code>obj</code> can be a token, or a locationData.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">addLocationDataFn</span></span> = (first, last) ->
|
||||
(obj) ->
|
||||
<span class="keyword">if</span> ((<span class="keyword">typeof</span> obj) <span class="keyword">is</span> <span class="string">'object'</span>) <span class="keyword">and</span> (!!obj[<span class="string">'updateLocationDataIfMissing'</span>])
|
||||
obj.updateLocationDataIfMissing buildLocationData(first, last)
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">locationDataToString</span> = <span class="hljs-params">(obj)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> (<span class="hljs-string">"2"</span> <span class="hljs-keyword">of</span> obj) <span class="hljs-keyword">and</span> (<span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj[<span class="hljs-number">2</span>]) <span class="hljs-keyword">then</span> locationData = obj[<span class="hljs-number">2</span>]
|
||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj <span class="hljs-keyword">then</span> locationData = obj
|
||||
|
||||
<span class="keyword">return</span> obj</pre></div></div>
|
||||
<span class="hljs-keyword">if</span> locationData
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{locationData.first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.first_column + <span class="hljs-number">1</span>}</span>-"</span> +
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{locationData.last_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.last_column + <span class="hljs-number">1</span>}</span>"</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-string">"No location data"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -423,21 +424,19 @@ The object is returned either way.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>Convert jison location data to a string.
|
||||
<code>obj</code> can be a token, or a locationData.
|
||||
</p>
|
||||
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">locationDataToString</span></span> = (obj) ->
|
||||
<span class="keyword">if</span> (<span class="string">"2"</span> <span class="keyword">of</span> obj) <span class="keyword">and</span> (<span class="string">"first_line"</span> <span class="keyword">of</span> obj[<span class="number">2</span>]) <span class="keyword">then</span> locationData = obj[<span class="number">2</span>]
|
||||
<span class="keyword">else</span> <span class="keyword">if</span> <span class="string">"first_line"</span> <span class="keyword">of</span> obj <span class="keyword">then</span> locationData = obj
|
||||
|
||||
<span class="keyword">if</span> locationData
|
||||
<span class="string">"<span class="subst">#{locationData.first_line + <span class="number">1</span>}</span>:<span class="subst">#{locationData.first_column + <span class="number">1</span>}</span>-"</span> +
|
||||
<span class="string">"<span class="subst">#{locationData.last_line + <span class="number">1</span>}</span>:<span class="subst">#{locationData.last_column + <span class="number">1</span>}</span>"</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="string">"No location data"</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">baseFileName</span> = <span class="hljs-params">(file, stripExt = <span class="hljs-literal">no</span>, useWinPathSep = <span class="hljs-literal">no</span>)</span> -></span>
|
||||
pathSep = <span class="hljs-keyword">if</span> useWinPathSep <span class="hljs-keyword">then</span> <span class="hljs-regexp">/\\|\//</span> <span class="hljs-keyword">else</span> <span class="hljs-regexp">/\/</span>/
|
||||
parts = file.split(pathSep)
|
||||
file = parts[parts.length - <span class="hljs-number">1</span>]
|
||||
<span class="hljs-keyword">return</span> file <span class="hljs-keyword">unless</span> stripExt <span class="hljs-keyword">and</span> file.indexOf(<span class="hljs-string">'.'</span>) >= <span class="hljs-number">0</span>
|
||||
parts = file.split(<span class="hljs-string">'.'</span>)
|
||||
parts.pop()
|
||||
parts.pop() <span class="hljs-keyword">if</span> parts[parts.length - <span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'coffee'</span> <span class="hljs-keyword">and</span> parts.length > <span class="hljs-number">1</span>
|
||||
parts.join(<span class="hljs-string">'.'</span>)</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -448,20 +447,11 @@ The object is returned either way.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.
|
||||
</p>
|
||||
<p>Determine if a filename represents a CoffeeScript file.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">baseFileName</span></span> = (file, stripExt = <span class="literal">no</span>, useWinPathSep = <span class="literal">no</span>) ->
|
||||
pathSep = <span class="keyword">if</span> useWinPathSep <span class="keyword">then</span> <span class="regexp">/\\|\// else /\//</span>
|
||||
parts = file.split(pathSep)
|
||||
file = parts[parts.length - <span class="number">1</span>]
|
||||
<span class="keyword">return</span> file <span class="keyword">unless</span> stripExt
|
||||
parts = file.split(<span class="string">'.'</span>)
|
||||
parts.pop()
|
||||
parts.pop() <span class="keyword">if</span> parts[parts.length - <span class="number">1</span>] <span class="keyword">is</span> <span class="string">'coffee'</span> <span class="keyword">and</span> parts.length > <span class="number">1</span>
|
||||
parts.join(<span class="string">'.'</span>)</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">isCoffee</span> = <span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -472,12 +462,11 @@ The object is returned either way.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>Determine if a filename represents a CoffeeScript file.
|
||||
</p>
|
||||
<p>Determine if a filename represents a Literate CoffeeScript file.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">isCoffee</span></span> = (file) -> <span class="regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">isLiterate</span> = <span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -488,12 +477,17 @@ The object is returned either way.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>Determine if a filename represents a Literate CoffeeScript file.
|
||||
</p>
|
||||
<p>Throws a SyntaxError from a given location.
|
||||
The error's <code>toString</code> will return an error message following the "standard"
|
||||
format <filename>:<line>:<col>: <message> plus the line with the error and a
|
||||
marker showing where the error is.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">isLiterate</span></span> = (file) -> <span class="regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">throwSyntaxError</span> = <span class="hljs-params">(message, location)</span> -></span>
|
||||
error = <span class="hljs-keyword">new</span> SyntaxError message
|
||||
error.location = location
|
||||
error.toString = syntaxErrorToString</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -504,18 +498,15 @@ The object is returned either way.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>Throws a SyntaxError with a source file location data attached to it in a
|
||||
property called <code>location</code>.
|
||||
</p>
|
||||
<p>Instead of showing the compiler's stacktrace, show our custom error message
|
||||
(this is useful when the error bubbles up in Node.js applications that
|
||||
compile CoffeeScript for example).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">throwSyntaxError</span></span> = (message, location) ->
|
||||
location.last_line ?= location.first_line
|
||||
location.last_column ?= location.first_column
|
||||
error = <span class="keyword">new</span> SyntaxError message
|
||||
error.location = location
|
||||
<span class="keyword">throw</span> error</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> error.stack = error.toString()
|
||||
|
||||
<span class="hljs-keyword">throw</span> error</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -526,20 +517,12 @@ property called <code>location</code>.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-22">¶</a>
|
||||
</div>
|
||||
<p>Creates a nice error message like, following the "standard" format
|
||||
</p>
|
||||
<p><filename>:<line>:<col>: <message> plus the line with the error and a marker
|
||||
showing where the error is.
|
||||
</p>
|
||||
<p>Update a compiler SyntaxError with source code information if it didn't have
|
||||
it already.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">prettyErrorMessage</span></span> = (error, fileName, code, useColors) ->
|
||||
<span class="keyword">return</span> error.stack <span class="keyword">or</span> <span class="string">"<span class="subst">#{error}</span>"</span> <span class="keyword">unless</span> error.location
|
||||
|
||||
{first_line, first_column, last_line, last_column} = error.location
|
||||
codeLine = code.split(<span class="string">'\n'</span>)[first_line]
|
||||
start = first_column</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">updateSyntaxError</span> = <span class="hljs-params">(error, code, filename)</span> -></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -550,24 +533,26 @@ showing where the error is.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-23">¶</a>
|
||||
</div>
|
||||
<p>Show only the first line on multi-line errors.
|
||||
</p>
|
||||
<p>Avoid screwing up the <code>stack</code> property of other errors (i.e. possible bugs).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> end = <span class="keyword">if</span> first_line <span class="keyword">is</span> last_line <span class="keyword">then</span> last_column + <span class="number">1</span> <span class="keyword">else</span> codeLine.length
|
||||
marker = repeat(<span class="string">' '</span>, start) + repeat(<span class="string">'^'</span>, end - start)
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> error.toString <span class="hljs-keyword">is</span> syntaxErrorToString
|
||||
error.code <span class="hljs-keyword">or</span>= code
|
||||
error.filename <span class="hljs-keyword">or</span>= filename
|
||||
error.stack = error.toString()
|
||||
error
|
||||
|
||||
<span class="keyword">if</span> useColors
|
||||
<span class="function"><span class="title">colorize</span></span> = (str) -> <span class="string">"\x1B[1;31m<span class="subst">#{str}</span>\x1B[0m"</span>
|
||||
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
|
||||
marker = colorize marker
|
||||
<span class="hljs-function"><span class="hljs-title">syntaxErrorToString</span> = -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-attribute">Error</span>::toString.call @ <span class="hljs-keyword">unless</span> <span class="hljs-property">@code</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@location</span>
|
||||
|
||||
message = <span class="string">"""
|
||||
<span class="subst">#{fileName}</span>:<span class="subst">#{first_line + <span class="number">1</span>}</span>:<span class="subst">#{first_column + <span class="number">1</span>}</span>: error: <span class="subst">#{error.message}</span>
|
||||
<span class="subst">#{codeLine}</span>
|
||||
<span class="subst">#{marker}</span>
|
||||
"""</span></pre></div></div>
|
||||
{first_line, first_column, last_line, last_column} = <span class="hljs-property">@location</span>
|
||||
last_line ?= first_line
|
||||
last_column ?= first_column
|
||||
|
||||
filename = <span class="hljs-property">@filename</span> <span class="hljs-keyword">or</span> <span class="hljs-string">'[stdin]'</span>
|
||||
codeLine = <span class="hljs-property">@code</span>.split(<span class="hljs-string">'\n'</span>)[first_line]
|
||||
start = first_column</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -578,14 +563,47 @@ showing where the error is.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-24">¶</a>
|
||||
</div>
|
||||
<p>Uncomment to add stacktrace.
|
||||
message += "\n#{error.stack}"
|
||||
</p>
|
||||
<p>Show only the first line on multi-line errors.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
message</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> end = <span class="hljs-keyword">if</span> first_line <span class="hljs-keyword">is</span> last_line <span class="hljs-keyword">then</span> last_column + <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> codeLine.length
|
||||
marker = repeat(<span class="hljs-string">' '</span>, start) + repeat(<span class="hljs-string">'^'</span>, end - start)</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-25">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-25">¶</a>
|
||||
</div>
|
||||
<p>Check to see if we're running on a color-enabled TTY.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> process?
|
||||
colorsEnabled = process.stdout.isTTY <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> process.env.NODE_DISABLE_COLORS
|
||||
|
||||
<span class="hljs-keyword">if</span> <span class="hljs-property">@colorful</span> ? colorsEnabled
|
||||
<span class="hljs-function"><span class="hljs-title">colorize</span> = <span class="hljs-params">(str)</span> -></span> <span class="hljs-string">"\x1B[1;31m<span class="hljs-subst">#{str}</span>\x1B[0m"</span>
|
||||
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
|
||||
marker = colorize marker
|
||||
|
||||
<span class="hljs-string">"""
|
||||
<span class="hljs-subst">#{filename}</span>:<span class="hljs-subst">#{first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{first_column + <span class="hljs-number">1</span>}</span>: error: <span class="hljs-subst">#{<span class="hljs-property">@message</span>}</span>
|
||||
<span class="hljs-subst">#{codeLine}</span>
|
||||
<span class="hljs-subst">#{marker}</span>
|
||||
"""</span>
|
||||
|
||||
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">nameWhitespaceCharacter</span> = <span class="hljs-params">(string)</span> -></span>
|
||||
<span class="hljs-keyword">switch</span> string
|
||||
<span class="hljs-keyword">when</span> <span class="hljs-string">' '</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'space'</span>
|
||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'newline'</span>
|
||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\r'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'carriage return'</span>
|
||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\t'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'tab'</span>
|
||||
<span class="hljs-keyword">else</span> string</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -108,12 +113,11 @@
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-1">¶</a>
|
||||
</div>
|
||||
<p>Loader for CoffeeScript as a Node.js library.
|
||||
</p>
|
||||
<p>Loader for CoffeeScript as a Node.js library.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports[key] = val <span class="keyword">for</span> key, val <span class="keyword">of</span> require <span class="string">'./coffee-script'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>[key] = val <span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,7 +116,7 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>{repeat} = require <span class="string">'./helpers'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre>{repeat} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -123,18 +128,15 @@
|
|||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
|
||||
Use it like so:
|
||||
|
||||
</p>
|
||||
Use it like so:</p>
|
||||
<pre><code>parser = new OptionParser switches, helpBanner
|
||||
options = parser.parse process.argv</code></pre>
|
||||
<p>The first non-option is considered to be the start of the file (and file
|
||||
option) list, and all subsequent arguments are left unparsed.
|
||||
</p>
|
||||
options = parser.parse process.argv
|
||||
</code></pre><p>The first non-option is considered to be the start of the file (and file
|
||||
option) list, and all subsequent arguments are left unparsed.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>exports.OptionParser = <span class="class"><span class="keyword">class</span> <span class="title">OptionParser</span></span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -145,17 +147,14 @@ option) list, and all subsequent arguments are left unparsed.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Initialize with a list of valid options, in the form:
|
||||
|
||||
</p>
|
||||
<pre><code>[short-flag, long-flag, description]</code></pre>
|
||||
<p>Along with an an optional banner for the usage help.
|
||||
</p>
|
||||
<p>Initialize with a list of valid options, in the form:</p>
|
||||
<pre><code>[short-flag, long-flag, description]
|
||||
</code></pre><p>Along with an an optional banner for the usage help.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> constructor: (rules, <span class="property">@banner</span>) ->
|
||||
<span class="property">@rules</span> = buildRules rules</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(rules, <span class="hljs-property">@banner</span>)</span> -></span>
|
||||
<span class="hljs-property">@rules</span> = buildRules rules</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -171,25 +170,24 @@ specified options, and return it. Options after the first non-option
|
|||
argument are treated as arguments. <code>options.arguments</code> will be an array
|
||||
containing the remaining arguments. This is a simpler API than many option
|
||||
parsers that allow you to attach callback actions for every flag. Instead,
|
||||
you're responsible for interpreting the options object.
|
||||
</p>
|
||||
you're responsible for interpreting the options object.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> parse: (args) ->
|
||||
options = arguments: []
|
||||
skippingArgument = <span class="literal">no</span>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">parse</span>: <span class="hljs-function"><span class="hljs-params">(args)</span> -></span>
|
||||
options = <span class="hljs-attribute">arguments</span>: []
|
||||
skippingArgument = <span class="hljs-literal">no</span>
|
||||
originalArgs = args
|
||||
args = normalizeArguments args
|
||||
<span class="keyword">for</span> arg, i <span class="keyword">in</span> args
|
||||
<span class="keyword">if</span> skippingArgument
|
||||
skippingArgument = <span class="literal">no</span>
|
||||
<span class="keyword">continue</span>
|
||||
<span class="keyword">if</span> arg <span class="keyword">is</span> <span class="string">'--'</span>
|
||||
pos = originalArgs.indexOf <span class="string">'--'</span>
|
||||
options.arguments = options.arguments.concat originalArgs[(pos + <span class="number">1</span>)..]
|
||||
<span class="keyword">break</span>
|
||||
isOption = !!(arg.match(LONG_FLAG) <span class="keyword">or</span> arg.match(SHORT_FLAG))</pre></div></div>
|
||||
<span class="hljs-keyword">for</span> arg, i <span class="hljs-keyword">in</span> args
|
||||
<span class="hljs-keyword">if</span> skippingArgument
|
||||
skippingArgument = <span class="hljs-literal">no</span>
|
||||
<span class="hljs-keyword">continue</span>
|
||||
<span class="hljs-keyword">if</span> arg <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
|
||||
pos = originalArgs.indexOf <span class="hljs-string">'--'</span>
|
||||
options.arguments = options.arguments.concat originalArgs[(pos + <span class="hljs-number">1</span>)..]
|
||||
<span class="hljs-keyword">break</span>
|
||||
isOption = !!(arg.match(LONG_FLAG) <span class="hljs-keyword">or</span> arg.match(SHORT_FLAG))</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -201,25 +199,24 @@ you're responsible for interpreting the options object.
|
|||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>the CS option parser is a little odd; options after the first
|
||||
non-option argument are treated as non-option arguments themselves
|
||||
</p>
|
||||
non-option argument are treated as non-option arguments themselves</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length > <span class="number">0</span>
|
||||
<span class="keyword">unless</span> seenNonOptionArg
|
||||
matchedRule = <span class="literal">no</span>
|
||||
<span class="keyword">for</span> rule <span class="keyword">in</span> <span class="property">@rules</span>
|
||||
<span class="keyword">if</span> rule.shortFlag <span class="keyword">is</span> arg <span class="keyword">or</span> rule.longFlag <span class="keyword">is</span> arg
|
||||
value = <span class="literal">true</span>
|
||||
<span class="keyword">if</span> rule.hasArgument
|
||||
skippingArgument = <span class="literal">yes</span>
|
||||
value = args[i + <span class="number">1</span>]
|
||||
options[rule.name] = <span class="keyword">if</span> rule.isList <span class="keyword">then</span> (options[rule.name] <span class="keyword">or</span> []).concat value <span class="keyword">else</span> value
|
||||
matchedRule = <span class="literal">yes</span>
|
||||
<span class="keyword">break</span>
|
||||
<span class="keyword">throw</span> <span class="keyword">new</span> Error <span class="string">"unrecognized option: <span class="subst">#{arg}</span>"</span> <span class="keyword">if</span> isOption <span class="keyword">and</span> <span class="keyword">not</span> matchedRule
|
||||
<span class="keyword">if</span> seenNonOptionArg <span class="keyword">or</span> <span class="keyword">not</span> isOption
|
||||
<div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length > <span class="hljs-number">0</span>
|
||||
<span class="hljs-keyword">unless</span> seenNonOptionArg
|
||||
matchedRule = <span class="hljs-literal">no</span>
|
||||
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> <span class="hljs-property">@rules</span>
|
||||
<span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">is</span> arg <span class="hljs-keyword">or</span> rule.longFlag <span class="hljs-keyword">is</span> arg
|
||||
value = <span class="hljs-literal">true</span>
|
||||
<span class="hljs-keyword">if</span> rule.hasArgument
|
||||
skippingArgument = <span class="hljs-literal">yes</span>
|
||||
value = args[i + <span class="hljs-number">1</span>]
|
||||
options[rule.name] = <span class="hljs-keyword">if</span> rule.isList <span class="hljs-keyword">then</span> (options[rule.name] <span class="hljs-keyword">or</span> []).concat value <span class="hljs-keyword">else</span> value
|
||||
matchedRule = <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-keyword">break</span>
|
||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option: <span class="hljs-subst">#{arg}</span>"</span> <span class="hljs-keyword">if</span> isOption <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> matchedRule
|
||||
<span class="hljs-keyword">if</span> seenNonOptionArg <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> isOption
|
||||
options.arguments.push arg
|
||||
options</pre></div></div>
|
||||
|
||||
|
@ -233,20 +230,19 @@ non-option argument are treated as non-option arguments themselves
|
|||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
|
||||
of the valid options, for <code>--help</code> and such.
|
||||
</p>
|
||||
of the valid options, for <code>--help</code> and such.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> help: ->
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">help</span>:<span class="hljs-function"> -></span>
|
||||
lines = []
|
||||
lines.unshift <span class="string">"<span class="subst">#{@banner}</span>\n"</span> <span class="keyword">if</span> <span class="property">@banner</span>
|
||||
<span class="keyword">for</span> rule <span class="keyword">in</span> <span class="property">@rules</span>
|
||||
spaces = <span class="number">15</span> - rule.longFlag.length
|
||||
spaces = <span class="keyword">if</span> spaces > <span class="number">0</span> <span class="keyword">then</span> repeat <span class="string">' '</span>, spaces <span class="keyword">else</span> <span class="string">''</span>
|
||||
letPart = <span class="keyword">if</span> rule.shortFlag <span class="keyword">then</span> rule.shortFlag + <span class="string">', '</span> <span class="keyword">else</span> <span class="string">' '</span>
|
||||
lines.push <span class="string">' '</span> + letPart + rule.longFlag + spaces + rule.description
|
||||
<span class="string">"\n<span class="subst">#{ lines.join('\n') }</span>\n"</span></pre></div></div>
|
||||
lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@banner</span>}</span>\n"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@banner</span>
|
||||
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> <span class="hljs-property">@rules</span>
|
||||
spaces = <span class="hljs-number">15</span> - rule.longFlag.length
|
||||
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||
letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
|
||||
lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
|
||||
<span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -254,10 +250,10 @@ of the valid options, for <code>--help</code> and such.
|
|||
<li id="section-7">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<h2>Helpers</h2>
|
||||
<h2 id="helpers">Helpers</h2>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -270,9 +266,15 @@ of the valid options, for <code>--help</code> and such.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Regex matchers for option flags.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="hljs-regexp">/^(--\w[\w\-]*)/</span>
|
||||
SHORT_FLAG = <span class="hljs-regexp">/^(-\w)$/</span>
|
||||
MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span>
|
||||
OPTIONAL = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -282,15 +284,15 @@ of the valid options, for <code>--help</code> and such.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Regex matchers for option flags.
|
||||
</p>
|
||||
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
|
||||
unspecified, leave it out by padding with <code>null</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="regexp">/^(--\w[\w\-]*)/</span>
|
||||
SHORT_FLAG = <span class="regexp">/^(-\w)$/</span>
|
||||
MULTI_FLAG = <span class="regexp">/^-(\w{2,})/</span>
|
||||
OPTIONAL = <span class="regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRules</span> = <span class="hljs-params">(rules)</span> -></span>
|
||||
<span class="hljs-keyword">for</span> tuple <span class="hljs-keyword">in</span> rules
|
||||
tuple.unshift <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> tuple.length < <span class="hljs-number">3</span>
|
||||
buildRule tuple...</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -301,16 +303,22 @@ OPTIONAL = <span class="regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
|
||||
unspecified, leave it out by padding with <code>null</code>.
|
||||
</p>
|
||||
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
|
||||
description of what the option does.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildRules</span></span> = (rules) ->
|
||||
<span class="keyword">for</span> tuple <span class="keyword">in</span> rules
|
||||
tuple.unshift <span class="literal">null</span> <span class="keyword">if</span> tuple.length < <span class="number">3</span>
|
||||
buildRule tuple...</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRule</span> = <span class="hljs-params">(shortFlag, longFlag, description, options = {})</span> -></span>
|
||||
match = longFlag.match(OPTIONAL)
|
||||
longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
|
||||
{
|
||||
<span class="hljs-attribute">name</span>: longFlag.substr <span class="hljs-number">2</span>
|
||||
<span class="hljs-attribute">shortFlag</span>: shortFlag
|
||||
<span class="hljs-attribute">longFlag</span>: longFlag
|
||||
<span class="hljs-attribute">description</span>: description
|
||||
<span class="hljs-attribute">hasArgument</span>: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">1</span>])
|
||||
<span class="hljs-attribute">isList</span>: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">2</span>])
|
||||
}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -321,46 +329,18 @@ unspecified, leave it out by padding with <code>null</code>.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
|
||||
description of what the option does.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildRule</span></span> = (shortFlag, longFlag, description, options = {}) ->
|
||||
match = longFlag.match(OPTIONAL)
|
||||
longFlag = longFlag.match(LONG_FLAG)[<span class="number">1</span>]
|
||||
{
|
||||
name: longFlag.substr <span class="number">2</span>
|
||||
shortFlag: shortFlag
|
||||
longFlag: longFlag
|
||||
description: description
|
||||
hasArgument: !!(match <span class="keyword">and</span> match[<span class="number">1</span>])
|
||||
isList: !!(match <span class="keyword">and</span> match[<span class="number">2</span>])
|
||||
}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-12">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>Normalize arguments by expanding merged flags into multiple flags. This allows
|
||||
you to have <code>-wl</code> be the same as <code>--watch --lint</code>.
|
||||
</p>
|
||||
you to have <code>-wl</code> be the same as <code>--watch --lint</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">normalizeArguments</span></span> = (args) ->
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">normalizeArguments</span> = <span class="hljs-params">(args)</span> -></span>
|
||||
args = args[..]
|
||||
result = []
|
||||
<span class="keyword">for</span> arg <span class="keyword">in</span> args
|
||||
<span class="keyword">if</span> match = arg.match MULTI_FLAG
|
||||
result.push <span class="string">'-'</span> + l <span class="keyword">for</span> l <span class="keyword">in</span> match[<span class="number">1</span>].split <span class="string">''</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> args
|
||||
<span class="hljs-keyword">if</span> match = arg.match MULTI_FLAG
|
||||
result.push <span class="hljs-string">'-'</span> + l <span class="hljs-keyword">for</span> l <span class="hljs-keyword">in</span> match[<span class="hljs-number">1</span>].split <span class="hljs-string">''</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
result.push arg
|
||||
result</pre></div></div>
|
||||
|
||||
|
|
251
documentation/docs/register.html
Normal file
251
documentation/docs/register.html
Normal file
|
@ -0,0 +1,251 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>register.coffee</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||
<link rel="stylesheet" media="all" href="docco.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="background"></div>
|
||||
|
||||
<ul id="jump_to">
|
||||
<li>
|
||||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||||
<a class="small" href="javascript:void(0);">+</a>
|
||||
<div id="jump_wrapper">
|
||||
<div id="jump_page">
|
||||
|
||||
|
||||
<a class="source" href="browser.html">
|
||||
browser.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="cake.html">
|
||||
cake.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="coffee-script.html">
|
||||
coffee-script.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="command.html">
|
||||
command.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="grammar.html">
|
||||
grammar.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="helpers.html">
|
||||
helpers.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="index.html">
|
||||
index.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="lexer.html">
|
||||
lexer.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="nodes.html">
|
||||
nodes.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="optparse.html">
|
||||
optparse.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="rewriter.html">
|
||||
rewriter.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="scope.html">
|
||||
scope.litcoffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="sourcemap.html">
|
||||
sourcemap.litcoffee
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="sections">
|
||||
|
||||
<li id="title">
|
||||
<div class="annotation">
|
||||
<h1>register.coffee</h1>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li id="section-1">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-1">¶</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span>
|
||||
child_process = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-2">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">loadFile</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>, filename)</span> -></span>
|
||||
answer = CoffeeScript._compileFile filename, <span class="hljs-literal">false</span>
|
||||
<span class="hljs-built_in">module</span>._compile answer, filename</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-3">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>If the installed version of Node supports <code>require.extensions</code>, register
|
||||
CoffeeScript as an extension.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.extensions
|
||||
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS
|
||||
<span class="hljs-built_in">require</span>.extensions[ext] = loadFile</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-4">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Patch Node's module loader to be able to handle mult-dot extensions.
|
||||
This is a horrible thing that should not be required. Perhaps, one day,
|
||||
when a truly benevolent dictator comes to rule over the Republik of Node,
|
||||
it won't be.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">findExtension</span> = <span class="hljs-params">(filename)</span> -></span>
|
||||
extensions = path.basename(filename).split <span class="hljs-string">'.'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-5">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Remove the initial dot from dotfiles.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> extensions.shift() <span class="hljs-keyword">if</span> extensions[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-6">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Start with the longest possible extension and work our way shortwards.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> extensions.shift()
|
||||
curExtension = <span class="hljs-string">'.'</span> + extensions.join <span class="hljs-string">'.'</span>
|
||||
<span class="hljs-keyword">return</span> curExtension <span class="hljs-keyword">if</span> Module._extensions[curExtension]
|
||||
<span class="hljs-string">'.js'</span>
|
||||
|
||||
<span class="hljs-attribute">Module</span>::<span class="hljs-function"><span class="hljs-title">load</span> = <span class="hljs-params">(filename)</span> -></span>
|
||||
<span class="hljs-property">@filename</span> = filename
|
||||
<span class="hljs-property">@paths</span> = Module._nodeModulePaths path.dirname filename
|
||||
extension = findExtension filename
|
||||
Module._extensions[extension](<span class="hljs-keyword">this</span>, filename)
|
||||
<span class="hljs-property">@loaded</span> = <span class="hljs-literal">true</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-7">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>If we're on Node, patch <code>child_process.fork</code> so that Coffee scripts are able
|
||||
to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> child_process
|
||||
{fork} = child_process
|
||||
binary = <span class="hljs-built_in">require</span>.resolve <span class="hljs-string">'../../bin/coffee'</span>
|
||||
child_process.<span class="hljs-function"><span class="hljs-title">fork</span> = <span class="hljs-params">(path, args, options)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> helpers.isCoffee path
|
||||
<span class="hljs-keyword">unless</span> Array.isArray args
|
||||
options = args <span class="hljs-keyword">or</span> {}
|
||||
args = []
|
||||
args = [path].concat args
|
||||
path = binary
|
||||
fork path, args, options</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,18 +116,18 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>fs = require <span class="string">'fs'</span>
|
||||
path = require <span class="string">'path'</span>
|
||||
vm = require <span class="string">'vm'</span>
|
||||
nodeREPL = require <span class="string">'repl'</span>
|
||||
CoffeeScript = require <span class="string">'./coffee-script'</span>
|
||||
{merge, prettyErrorMessage} = require <span class="string">'./helpers'</span>
|
||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
||||
nodeREPL = <span class="hljs-built_in">require</span> <span class="hljs-string">'repl'</span>
|
||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span>
|
||||
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
|
||||
replDefaults =
|
||||
prompt: <span class="string">'coffee> '</span>,
|
||||
historyFile: path.join process.env.HOME, <span class="string">'.coffee_history'</span> <span class="keyword">if</span> process.env.HOME
|
||||
historyMaxInputSize: <span class="number">10240</span>
|
||||
eval: (input, context, filename, cb) -></pre></div></div>
|
||||
<span class="hljs-attribute">prompt</span>: <span class="hljs-string">'coffee> '</span>,
|
||||
<span class="hljs-attribute">historyFile</span>: path.join process.env.HOME, <span class="hljs-string">'.coffee_history'</span> <span class="hljs-keyword">if</span> process.env.HOME
|
||||
<span class="hljs-attribute">historyMaxInputSize</span>: <span class="hljs-number">10240</span>
|
||||
<span class="hljs-attribute">eval</span>: <span class="hljs-function"><span class="hljs-params">(input, context, filename, cb)</span> -></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -133,12 +138,11 @@ replDefaults =
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>XXX: multiline hack.
|
||||
</p>
|
||||
<p>XXX: multiline hack.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="regexp">/\uFF00/g</span>, <span class="string">'\n'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/\uFF00/g</span>, <span class="hljs-string">'\n'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -150,12 +154,11 @@ replDefaults =
|
|||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Node's REPL sends the input ending with a newline and then wrapped in
|
||||
parens. Unwrap all that.
|
||||
</p>
|
||||
parens. Unwrap all that.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="regexp">/^\(([\s\S]*)\n\)$/m</span>, <span class="string">'$1'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/^\(([\s\S]*)\n\)$/m</span>, <span class="hljs-string">'$1'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -166,14 +169,13 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Require AST nodes to do some AST manipulation.
|
||||
</p>
|
||||
<p>Require AST nodes to do some AST manipulation.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal} = require <span class="string">'./nodes'</span>
|
||||
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
|
||||
|
||||
<span class="keyword">try</span></pre></div></div>
|
||||
<span class="hljs-keyword">try</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -184,8 +186,7 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Generate the AST of the clean input.
|
||||
</p>
|
||||
<p>Generate the AST of the clean input.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -200,27 +201,20 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Add assignment to <code>_</code> variable to force the input to be an expression.
|
||||
</p>
|
||||
<p>Add assignment to <code>_</code> variable to force the input to be an expression.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> ast = <span class="keyword">new</span> Block [
|
||||
<span class="keyword">new</span> Assign (<span class="keyword">new</span> Value <span class="keyword">new</span> Literal <span class="string">'_'</span>), ast, <span class="string">'='</span>
|
||||
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [
|
||||
<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'_'</span>), ast, <span class="hljs-string">'='</span>
|
||||
]
|
||||
js = ast.compile bare: <span class="literal">yes</span>, locals: Object.keys(context)
|
||||
cb <span class="literal">null</span>, vm.runInContext(js, context, filename)
|
||||
<span class="keyword">catch</span> err
|
||||
cb prettyErrorMessage(err, filename, input, <span class="literal">yes</span>)
|
||||
|
||||
<span class="function"><span class="title">addMultilineHandler</span></span> = (repl) ->
|
||||
{rli, inputStream, outputStream} = repl
|
||||
|
||||
multiline =
|
||||
enabled: <span class="literal">off</span>
|
||||
initialPrompt: repl.prompt.replace <span class="regexp">/^[^> ]*/, (x) -> x.replace /./g</span>, <span class="string">'-'</span>
|
||||
prompt: repl.prompt.replace <span class="regexp">/^[^> ]*>?/, (x) -> x.replace /./g</span>, <span class="string">'.'</span>
|
||||
buffer: <span class="string">''</span></pre></div></div>
|
||||
js = ast.compile <span class="hljs-attribute">bare</span>: <span class="hljs-literal">yes</span>, <span class="hljs-attribute">locals</span>: Object.keys(context)
|
||||
result = <span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
|
||||
vm.runInThisContext js, filename
|
||||
<span class="hljs-keyword">else</span>
|
||||
vm.runInContext js, context, filename
|
||||
cb <span class="hljs-literal">null</span>, result
|
||||
<span class="hljs-keyword">catch</span> err</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -231,21 +225,21 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Proxy node's line listener
|
||||
</p>
|
||||
<p>AST's <code>compile</code> does not add source code information to syntax errors.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> nodeLineListener = rli.listeners(<span class="string">'line'</span>)[<span class="number">0</span>]
|
||||
rli.removeListener <span class="string">'line'</span>, nodeLineListener
|
||||
rli.<span class="literal">on</span> <span class="string">'line'</span>, (cmd) ->
|
||||
<span class="keyword">if</span> multiline.enabled
|
||||
multiline.buffer += <span class="string">"<span class="subst">#{cmd}</span>\n"</span>
|
||||
rli.setPrompt multiline.prompt
|
||||
rli.prompt <span class="literal">true</span>
|
||||
<span class="keyword">else</span>
|
||||
nodeLineListener cmd
|
||||
<span class="keyword">return</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> updateSyntaxError err, input
|
||||
cb err
|
||||
|
||||
<span class="hljs-function"><span class="hljs-title">addMultilineHandler</span> = <span class="hljs-params">(repl)</span> -></span>
|
||||
{rli, inputStream, outputStream} = repl
|
||||
|
||||
multiline =
|
||||
<span class="hljs-attribute">enabled</span>: <span class="hljs-literal">off</span>
|
||||
<span class="hljs-attribute">initialPrompt</span>: repl.prompt.replace <span class="hljs-regexp">/^[^> ]*/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'-'</span>
|
||||
<span class="hljs-attribute">prompt</span>: repl.prompt.replace <span class="hljs-regexp">/^[^> ]*>?/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'.'</span>
|
||||
<span class="hljs-attribute">buffer</span>: <span class="hljs-string">''</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -256,14 +250,20 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Handle Ctrl-v
|
||||
</p>
|
||||
<p>Proxy node's line listener</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> inputStream.<span class="literal">on</span> <span class="string">'keypress'</span>, (char, key) ->
|
||||
<span class="keyword">return</span> <span class="keyword">unless</span> key <span class="keyword">and</span> key.ctrl <span class="keyword">and</span> <span class="keyword">not</span> key.meta <span class="keyword">and</span> <span class="keyword">not</span> key.shift <span class="keyword">and</span> key.name <span class="keyword">is</span> <span class="string">'v'</span>
|
||||
<span class="keyword">if</span> multiline.enabled</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> nodeLineListener = rli.listeners(<span class="hljs-string">'line'</span>)[<span class="hljs-number">0</span>]
|
||||
rli.removeListener <span class="hljs-string">'line'</span>, nodeLineListener
|
||||
rli.<span class="hljs-literal">on</span> <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(cmd)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> multiline.enabled
|
||||
multiline.buffer += <span class="hljs-string">"<span class="hljs-subst">#{cmd}</span>\n"</span>
|
||||
rli.setPrompt multiline.prompt
|
||||
rli.prompt <span class="hljs-literal">true</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
nodeLineListener cmd
|
||||
<span class="hljs-keyword">return</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -274,16 +274,13 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>allow arbitrarily switching between modes any time before multiple lines are entered
|
||||
</p>
|
||||
<p>Handle Ctrl-v</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">unless</span> multiline.buffer.match <span class="regexp">/\n/</span>
|
||||
multiline.enabled = <span class="keyword">not</span> multiline.enabled
|
||||
rli.setPrompt repl.prompt
|
||||
rli.prompt <span class="literal">true</span>
|
||||
<span class="keyword">return</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> inputStream.<span class="hljs-literal">on</span> <span class="hljs-string">'keypress'</span>, <span class="hljs-function"><span class="hljs-params">(char, key)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> key <span class="hljs-keyword">and</span> key.ctrl <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.meta <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.shift <span class="hljs-keyword">and</span> key.name <span class="hljs-keyword">is</span> <span class="hljs-string">'v'</span>
|
||||
<span class="hljs-keyword">if</span> multiline.enabled</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -294,12 +291,15 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>no-op unless the current line is empty
|
||||
</p>
|
||||
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">return</span> <span class="keyword">if</span> rli.line? <span class="keyword">and</span> <span class="keyword">not</span> rli.line.match <span class="regexp">/^\s*$/</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> multiline.buffer.match <span class="hljs-regexp">/\n/</span>
|
||||
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||
rli.setPrompt repl.prompt
|
||||
rli.prompt <span class="hljs-literal">true</span>
|
||||
<span class="hljs-keyword">return</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -310,16 +310,11 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>eval, print, loop
|
||||
</p>
|
||||
<p>no-op unless the current line is empty</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> multiline.enabled = <span class="keyword">not</span> multiline.enabled
|
||||
rli.line = <span class="string">''</span>
|
||||
rli.cursor = <span class="number">0</span>
|
||||
rli.output.cursorTo <span class="number">0</span>
|
||||
rli.output.clearLine <span class="number">1</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> rli.line? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> rli.line.match <span class="hljs-regexp">/^\s*$/</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -330,19 +325,15 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>XXX: multiline hack
|
||||
</p>
|
||||
<p>eval, print, loop</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> multiline.buffer = multiline.buffer.replace <span class="regexp">/\n/g</span>, <span class="string">'\uFF00'</span>
|
||||
rli.emit <span class="string">'line'</span>, multiline.buffer
|
||||
multiline.buffer = <span class="string">''</span>
|
||||
<span class="keyword">else</span>
|
||||
multiline.enabled = <span class="keyword">not</span> multiline.enabled
|
||||
rli.setPrompt multiline.initialPrompt
|
||||
rli.prompt <span class="literal">true</span>
|
||||
<span class="keyword">return</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||
rli.line = <span class="hljs-string">''</span>
|
||||
rli.cursor = <span class="hljs-number">0</span>
|
||||
rli.output.cursorTo <span class="hljs-number">0</span>
|
||||
rli.output.clearLine <span class="hljs-number">1</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -353,14 +344,18 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Store and load command history from a file
|
||||
</p>
|
||||
<p>XXX: multiline hack</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">addHistory</span></span> = (repl, filename, maxSize) ->
|
||||
lastLine = <span class="literal">null</span>
|
||||
<span class="keyword">try</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> multiline.buffer = multiline.buffer.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">'\uFF00'</span>
|
||||
rli.emit <span class="hljs-string">'line'</span>, multiline.buffer
|
||||
multiline.buffer = <span class="hljs-string">''</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||
rli.setPrompt multiline.initialPrompt
|
||||
rli.prompt <span class="hljs-literal">true</span>
|
||||
<span class="hljs-keyword">return</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -371,13 +366,13 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Get file info and at most maxSize of command history
|
||||
</p>
|
||||
<p>Store and load command history from a file</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> stat = fs.statSync filename
|
||||
size = Math.min maxSize, stat.size</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">addHistory</span> = <span class="hljs-params">(repl, filename, maxSize)</span> -></span>
|
||||
lastLine = <span class="hljs-literal">null</span>
|
||||
<span class="hljs-keyword">try</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -388,14 +383,12 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Read last <code>size</code> bytes from the file
|
||||
</p>
|
||||
<p>Get file info and at most maxSize of command history</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> readFd = fs.openSync filename, <span class="string">'r'</span>
|
||||
buffer = <span class="keyword">new</span> Buffer(size)
|
||||
fs.readSync readFd, buffer, <span class="number">0</span>, size, stat.size - size</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> stat = fs.statSync filename
|
||||
size = Math.min maxSize, stat.size</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -406,12 +399,13 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>Set the history on the interpreter
|
||||
</p>
|
||||
<p>Read last <code>size</code> bytes from the file</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history = buffer.toString().split(<span class="string">'\n'</span>).reverse()</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> readFd = fs.openSync filename, <span class="hljs-string">'r'</span>
|
||||
buffer = <span class="hljs-keyword">new</span> Buffer(size)
|
||||
fs.readSync readFd, buffer, <span class="hljs-number">0</span>, size, stat.size - size</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -422,12 +416,11 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>If the history file was truncated we should pop off a potential partial line
|
||||
</p>
|
||||
<p>Set the history on the interpreter</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history.pop() <span class="keyword">if</span> stat.size > maxSize</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history = buffer.toString().split(<span class="hljs-string">'\n'</span>).reverse()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -438,19 +431,11 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>Shift off the final blank newline
|
||||
</p>
|
||||
<p>If the history file was truncated we should pop off a potential partial line</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history.shift() <span class="keyword">if</span> repl.rli.history[<span class="number">0</span>] <span class="keyword">is</span> <span class="string">''</span>
|
||||
repl.rli.historyIndex = -<span class="number">1</span>
|
||||
lastLine = repl.rli.history[<span class="number">0</span>]
|
||||
|
||||
fd = fs.openSync filename, <span class="string">'a'</span>
|
||||
|
||||
repl.rli.addListener <span class="string">'line'</span>, (code) ->
|
||||
<span class="keyword">if</span> code <span class="keyword">and</span> code.length <span class="keyword">and</span> code <span class="keyword">isnt</span> <span class="string">'.history'</span> <span class="keyword">and</span> lastLine <span class="keyword">isnt</span> code</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history.pop() <span class="hljs-keyword">if</span> stat.size > maxSize</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -461,15 +446,18 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>Save the latest command in the file
|
||||
</p>
|
||||
<p>Shift off the final blank newline</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> fs.write fd, <span class="string">"<span class="subst">#{code}</span>\n"</span>
|
||||
lastLine = code
|
||||
<div class="content"><div class='highlight'><pre> repl.rli.history.shift() <span class="hljs-keyword">if</span> repl.rli.history[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
||||
repl.rli.historyIndex = -<span class="hljs-number">1</span>
|
||||
lastLine = repl.rli.history[<span class="hljs-number">0</span>]
|
||||
|
||||
repl.rli.<span class="literal">on</span> <span class="string">'exit'</span>, -> fs.close fd</pre></div></div>
|
||||
fd = fs.openSync filename, <span class="hljs-string">'a'</span>
|
||||
|
||||
repl.rli.addListener <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> code <span class="hljs-keyword">and</span> code.length <span class="hljs-keyword">and</span> code <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.history'</span> <span class="hljs-keyword">and</span> lastLine <span class="hljs-keyword">isnt</span> code</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -480,30 +468,49 @@ parens. Unwrap all that.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>Add a command to show the history stack
|
||||
</p>
|
||||
<p>Save the latest command in the file</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> repl.commands[<span class="string">'.history'</span>] =
|
||||
help: <span class="string">'Show command history'</span>
|
||||
action: ->
|
||||
repl.outputStream.write <span class="string">"<span class="subst">#{repl.rli.history[..].reverse().join '\n'}</span>\n"</span>
|
||||
<div class="content"><div class='highlight'><pre> fs.write fd, <span class="hljs-string">"<span class="hljs-subst">#{code}</span>\n"</span>
|
||||
lastLine = code
|
||||
|
||||
repl.rli.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>,<span class="hljs-function"> -></span> fs.close fd</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-21">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>Add a command to show the history stack</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> repl.commands[<span class="hljs-string">'.history'</span>] =
|
||||
<span class="hljs-attribute">help</span>: <span class="hljs-string">'Show command history'</span>
|
||||
<span class="hljs-attribute">action</span>:<span class="hljs-function"> -></span>
|
||||
repl.outputStream.write <span class="hljs-string">"<span class="hljs-subst">#{repl.rli.history[..].reverse().join <span class="hljs-string">'\n'</span>}</span>\n"</span>
|
||||
repl.displayPrompt()
|
||||
|
||||
module.exports =
|
||||
start: (opts = {}) ->
|
||||
[major, minor, build] = process.versions.node.split(<span class="string">'.'</span>).map (n) -> parseInt(n)
|
||||
<span class="hljs-built_in">module</span>.<span class="hljs-built_in">exports</span> =
|
||||
<span class="hljs-attribute">start</span>: <span class="hljs-function"><span class="hljs-params">(opts = {})</span> -></span>
|
||||
[major, minor, build] = process.versions.node.split<span class="hljs-function"><span class="hljs-params">(<span class="hljs-string">'.'</span>)</span>.<span class="hljs-title">map</span> <span class="hljs-params">(n)</span> -></span> parseInt(n)
|
||||
|
||||
<span class="keyword">if</span> major <span class="keyword">is</span> <span class="number">0</span> <span class="keyword">and</span> minor < <span class="number">8</span>
|
||||
console.warn <span class="string">"Node 0.8.0+ required for CoffeeScript REPL"</span>
|
||||
process.exit <span class="number">1</span>
|
||||
<span class="hljs-keyword">if</span> major <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> minor < <span class="hljs-number">8</span>
|
||||
<span class="hljs-built_in">console</span>.warn <span class="hljs-string">"Node 0.8.0+ required for CoffeeScript REPL"</span>
|
||||
process.exit <span class="hljs-number">1</span>
|
||||
|
||||
CoffeeScript.register()
|
||||
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
|
||||
opts = merge replDefaults, opts
|
||||
repl = nodeREPL.start opts
|
||||
repl.<span class="literal">on</span> <span class="string">'exit'</span>, -> repl.outputStream.write <span class="string">'\n'</span>
|
||||
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>,<span class="hljs-function"> -></span> repl.outputStream.write <span class="hljs-string">'\n'</span>
|
||||
addMultilineHandler repl
|
||||
addHistory repl, opts.historyFile, opts.historyMaxInputSize <span class="keyword">if</span> opts.historyFile
|
||||
addHistory repl, opts.historyFile, opts.historyMaxInputSize <span class="hljs-keyword">if</span> opts.historyFile
|
||||
repl</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -113,11 +118,15 @@ generate code, you create a tree of scopes in the same shape as the nested
|
|||
function bodies. Each scope knows about the variables declared within it,
|
||||
and has a reference to its parent enclosing scope. In this way, we know which
|
||||
variables are new and need to be declared with <code>var</code>, and which are shared
|
||||
with external scopes.
|
||||
</p>
|
||||
with external scopes.</p>
|
||||
<p>Import the helpers we plan to use.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>{extend, last} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||
|
||||
<span class="hljs-built_in">exports</span>.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -127,15 +136,11 @@ with external scopes.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>Import the helpers we plan to use.
|
||||
</p>
|
||||
<p>The <code>root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
{extend, last} = require <span class="string">'./helpers'</span>
|
||||
|
||||
exports.Scope = <span class="class"><span class="keyword">class</span> <span class="title">Scope</span></span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-property">@root</span>: <span class="hljs-literal">null</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -146,13 +151,17 @@ exports.Scope = <span class="class"><span class="keyword">class</span> <span cla
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>The <code>root</code> is the top-level <strong>Scope</strong> object for a given file.
|
||||
</p>
|
||||
<p>Initialize a scope with its parent, for lookups up the chain,
|
||||
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
||||
where it should declare its variables, and a reference to the function that
|
||||
it belongs to.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
<span class="property">@root</span>: <span class="literal">null</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@parent</span>, <span class="hljs-property">@expressions</span>, <span class="hljs-property">@method</span>)</span> -></span>
|
||||
<span class="hljs-property">@variables</span> = [{<span class="hljs-attribute">name</span>: <span class="hljs-string">'arguments'</span>, <span class="hljs-attribute">type</span>: <span class="hljs-string">'arguments'</span>}]
|
||||
<span class="hljs-property">@positions</span> = {}
|
||||
Scope.root = <span class="hljs-keyword">this</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@parent</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -163,19 +172,16 @@ exports.Scope = <span class="class"><span class="keyword">class</span> <span cla
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Initialize a scope with its parent, for lookups up the chain,
|
||||
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
||||
where it should declare its variables, and a reference to the function that
|
||||
it belongs to.
|
||||
</p>
|
||||
<p>Adds a new variable or overrides an existing one.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
constructor: (<span class="property">@parent</span>, <span class="property">@expressions</span>, <span class="property">@method</span>) ->
|
||||
<span class="property">@variables</span> = [{name: <span class="string">'arguments'</span>, type: <span class="string">'arguments'</span>}]
|
||||
<span class="property">@positions</span> = {}
|
||||
Scope.root = <span class="keyword">this</span> <span class="keyword">unless</span> <span class="property">@parent</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">add</span>: <span class="hljs-function"><span class="hljs-params">(name, type, immediate)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-property">@parent</span>.add name, type, immediate <span class="hljs-keyword">if</span> <span class="hljs-property">@shared</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> immediate
|
||||
<span class="hljs-keyword">if</span> <span class="hljs-attribute">Object</span>::hasOwnProperty.call <span class="hljs-property">@positions</span>, name
|
||||
<span class="hljs-property">@variables</span>[<span class="hljs-property">@positions</span>[name]].type = type
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-property">@positions</span>[name] = <span class="hljs-property">@variables</span>.push({name, type}) - <span class="hljs-number">1</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -186,18 +192,17 @@ it belongs to.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Adds a new variable or overrides an existing one.
|
||||
</p>
|
||||
<p>When <code>super</code> is called, we need to find the name of the current method we're
|
||||
in, so that we know how to invoke the same method of the parent class. This
|
||||
can get complicated if super is being called from an inner function.
|
||||
<code>namedMethod</code> will walk up the scope tree until it either finds the first
|
||||
function object that has a name filled in, or bottoms out.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
add: (name, type, immediate) ->
|
||||
<span class="keyword">return</span> <span class="property">@parent</span>.add name, type, immediate <span class="keyword">if</span> <span class="property">@shared</span> <span class="keyword">and</span> <span class="keyword">not</span> immediate
|
||||
<span class="keyword">if</span> Object::hasOwnProperty.call <span class="property">@positions</span>, name
|
||||
<span class="property">@variables</span>[<span class="property">@positions</span>[name]].type = type
|
||||
<span class="keyword">else</span>
|
||||
<span class="property">@positions</span>[name] = <span class="property">@variables</span>.push({name, type}) - <span class="number">1</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">namedMethod</span>:<span class="hljs-function"> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-property">@method</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@method</span>?.name <span class="hljs-keyword">or</span> !<span class="hljs-property">@parent</span>
|
||||
<span class="hljs-property">@parent</span>.namedMethod()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -208,19 +213,15 @@ it belongs to.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>When <code>super</code> is called, we need to find the name of the current method we're
|
||||
in, so that we know how to invoke the same method of the parent class. This
|
||||
can get complicated if super is being called from an inner function.
|
||||
<code>namedMethod</code> will walk up the scope tree until it either finds the first
|
||||
function object that has a name filled in, or bottoms out.
|
||||
</p>
|
||||
<p>Look up a variable name in lexical scope, and declare it if it does not
|
||||
already exist.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
namedMethod: ->
|
||||
<span class="keyword">return</span> <span class="property">@method</span> <span class="keyword">if</span> <span class="property">@method</span>?.name <span class="keyword">or</span> !<span class="property">@parent</span>
|
||||
<span class="property">@parent</span>.namedMethod()</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">find</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@check</span> name
|
||||
<span class="hljs-property">@add</span> name, <span class="hljs-string">'var'</span>
|
||||
<span class="hljs-literal">no</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -231,17 +232,14 @@ function object that has a name filled in, or bottoms out.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Look up a variable name in lexical scope, and declare it if it does not
|
||||
already exist.
|
||||
</p>
|
||||
<p>Reserve a variable name as originating from a function parameter for this
|
||||
scope. No <code>var</code> required for internal references.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
find: (name) ->
|
||||
<span class="keyword">return</span> <span class="literal">yes</span> <span class="keyword">if</span> <span class="property">@check</span> name
|
||||
<span class="property">@add</span> name, <span class="string">'var'</span>
|
||||
<span class="literal">no</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">parameter</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@shared</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@parent</span>.check name, <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-property">@add</span> name, <span class="hljs-string">'param'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -252,16 +250,13 @@ already exist.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Reserve a variable name as originating from a function parameter for this
|
||||
scope. No <code>var</code> required for internal references.
|
||||
</p>
|
||||
<p>Just check to see if a variable has already been declared, without reserving,
|
||||
walks up to the root scope.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
parameter: (name) ->
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> <span class="property">@shared</span> <span class="keyword">and</span> <span class="property">@parent</span>.check name, <span class="literal">yes</span>
|
||||
<span class="property">@add</span> name, <span class="string">'param'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">check</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||
!!(<span class="hljs-property">@type</span>(name) <span class="hljs-keyword">or</span> <span class="hljs-property">@parent</span>?.check(name))</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -272,15 +267,15 @@ scope. No <code>var</code> required for internal references.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Just check to see if a variable has already been declared, without reserving,
|
||||
walks up to the root scope.
|
||||
</p>
|
||||
<p>Generate a temporary variable name at the given index.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
check: (name) ->
|
||||
!!(<span class="property">@type</span>(name) <span class="keyword">or</span> <span class="property">@parent</span>?.check(name))</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">temporary</span>: <span class="hljs-function"><span class="hljs-params">(name, index)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> name.length > <span class="hljs-number">1</span>
|
||||
<span class="hljs-string">'_'</span> + name + <span class="hljs-keyword">if</span> index > <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> index - <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||
<span class="hljs-keyword">else</span>
|
||||
<span class="hljs-string">'_'</span> + (index + parseInt name, <span class="hljs-number">36</span>).toString(<span class="hljs-number">36</span>).replace <span class="hljs-regexp">/\d/g</span>, <span class="hljs-string">'a'</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -291,17 +286,13 @@ walks up to the root scope.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Generate a temporary variable name at the given index.
|
||||
</p>
|
||||
<p>Gets the type of a variable.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
temporary: (name, index) ->
|
||||
<span class="keyword">if</span> name.length > <span class="number">1</span>
|
||||
<span class="string">'_'</span> + name + <span class="keyword">if</span> index > <span class="number">1</span> <span class="keyword">then</span> index - <span class="number">1</span> <span class="keyword">else</span> <span class="string">''</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="string">'_'</span> + (index + parseInt name, <span class="number">36</span>).toString(<span class="number">36</span>).replace <span class="regexp">/\d/g</span>, <span class="string">'a'</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">type</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||
<span class="hljs-keyword">return</span> v.type <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.name <span class="hljs-keyword">is</span> name
|
||||
<span class="hljs-literal">null</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -312,15 +303,16 @@ walks up to the root scope.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Gets the type of a variable.
|
||||
</p>
|
||||
<p>If we need to store an intermediate result, find an available name for a
|
||||
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
type: (name) ->
|
||||
<span class="keyword">return</span> v.type <span class="keyword">for</span> v <span class="keyword">in</span> <span class="property">@variables</span> <span class="keyword">when</span> v.name <span class="keyword">is</span> name
|
||||
<span class="literal">null</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">freeVariable</span>: <span class="hljs-function"><span class="hljs-params">(name, reserve=<span class="hljs-literal">true</span>)</span> -></span>
|
||||
index = <span class="hljs-number">0</span>
|
||||
index++ <span class="hljs-keyword">while</span> <span class="hljs-property">@check</span>((temp = <span class="hljs-property">@temporary</span> name, index))
|
||||
<span class="hljs-property">@add</span> temp, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> reserve
|
||||
temp</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -331,18 +323,14 @@ walks up to the root scope.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>If we need to store an intermediate result, find an available name for a
|
||||
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
|
||||
</p>
|
||||
<p>Ensure that an assignment is made at the top of this scope
|
||||
(or at the top-level scope, if requested).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
freeVariable: (name, reserve=<span class="literal">true</span>) ->
|
||||
index = <span class="number">0</span>
|
||||
index++ <span class="keyword">while</span> <span class="property">@check</span>((temp = <span class="property">@temporary</span> name, index))
|
||||
<span class="property">@add</span> temp, <span class="string">'var'</span>, <span class="literal">yes</span> <span class="keyword">if</span> reserve
|
||||
temp</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">assign</span>: <span class="hljs-function"><span class="hljs-params">(name, value)</span> -></span>
|
||||
<span class="hljs-property">@add</span> name, {value, <span class="hljs-attribute">assigned</span>: <span class="hljs-literal">yes</span>}, <span class="hljs-literal">yes</span>
|
||||
<span class="hljs-property">@hasAssignments</span> = <span class="hljs-literal">yes</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -353,16 +341,12 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Ensure that an assignment is made at the top of this scope
|
||||
(or at the top-level scope, if requested).
|
||||
</p>
|
||||
<p>Does this scope have any declared variables?</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
assign: (name, value) ->
|
||||
<span class="property">@add</span> name, {value, assigned: <span class="literal">yes</span>}, <span class="literal">yes</span>
|
||||
<span class="property">@hasAssignments</span> = <span class="literal">yes</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">hasDeclarations</span>:<span class="hljs-function"> -></span>
|
||||
!!<span class="hljs-property">@declaredVariables</span>().length</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -373,14 +357,16 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Does this scope have any declared variables?
|
||||
</p>
|
||||
<p>Return the list of variables first declared in this scope.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
hasDeclarations: ->
|
||||
!!<span class="property">@declaredVariables</span>().length</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">declaredVariables</span>:<span class="hljs-function"> -></span>
|
||||
realVars = []
|
||||
tempVars = []
|
||||
<span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.type <span class="hljs-keyword">is</span> <span class="hljs-string">'var'</span>
|
||||
(<span class="hljs-keyword">if</span> v.name.charAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'_'</span> <span class="hljs-keyword">then</span> tempVars <span class="hljs-keyword">else</span> realVars).push v.name
|
||||
realVars.sort().concat tempVars.sort()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -391,37 +377,13 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Return the list of variables first declared in this scope.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
declaredVariables: ->
|
||||
realVars = []
|
||||
tempVars = []
|
||||
<span class="keyword">for</span> v <span class="keyword">in</span> <span class="property">@variables</span> <span class="keyword">when</span> v.type <span class="keyword">is</span> <span class="string">'var'</span>
|
||||
(<span class="keyword">if</span> v.name.charAt(<span class="number">0</span>) <span class="keyword">is</span> <span class="string">'_'</span> <span class="keyword">then</span> tempVars <span class="keyword">else</span> realVars).push v.name
|
||||
realVars.sort().concat tempVars.sort()</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-16">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>Return the list of assignments that are supposed to be made at the top
|
||||
of this scope.
|
||||
</p>
|
||||
of this scope.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
assignedVariables: ->
|
||||
<span class="string">"<span class="subst">#{v.name}</span> = <span class="subst">#{v.type.value}</span>"</span> <span class="keyword">for</span> v <span class="keyword">in</span> <span class="property">@variables</span> <span class="keyword">when</span> v.type.assigned</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">assignedVariables</span>:<span class="hljs-function"> -></span>
|
||||
<span class="hljs-string">"<span class="hljs-subst">#{v.name}</span> = <span class="hljs-subst">#{v.type.value}</span>"</span> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.type.assigned</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
</a>
|
||||
|
||||
|
||||
<a class="source" href="register.html">
|
||||
register.coffee
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="repl.html">
|
||||
repl.coffee
|
||||
</a>
|
||||
|
@ -111,8 +116,13 @@
|
|||
<p>Source maps allow JavaScript runtimes to match running JavaScript back to
|
||||
the original source code that corresponds to it. This can be minified
|
||||
JavaScript, but in our case, we're concerned with mapping pretty-printed
|
||||
JavaScript back to CoffeeScript.
|
||||
</p>
|
||||
JavaScript back to CoffeeScript.</p>
|
||||
<p>In order to produce maps, we must keep track of positions (line number, column number)
|
||||
that originated every node in the syntax tree, and be able to generate a
|
||||
<a href="https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit">map file</a>
|
||||
— which is a compact, VLQ-encoded representation of the JSON serialization
|
||||
of this information — to write out alongside the generated JavaScript.</p>
|
||||
<h2 id="linemap">LineMap</h2>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -125,25 +135,34 @@ JavaScript back to CoffeeScript.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>In order to produce maps, we must keep track of positions (line number, column number)
|
||||
that originated every node in the syntax tree, and be able to generate a
|
||||
<a href="https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit">map file</a>
|
||||
— which is a compact, VLQ-encoded representation of the JSON serialization
|
||||
of this information — to write out alongside the generated JavaScript.
|
||||
</p>
|
||||
<p>A <strong>LineMap</strong> object keeps track of information about original line and column
|
||||
positions for a single line of output JavaScript code.
|
||||
<strong>SourceMaps</strong> are implemented in terms of <strong>LineMaps</strong>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineMap</span></span>
|
||||
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@line</span>)</span> -></span>
|
||||
<span class="hljs-property">@columns</span> = []
|
||||
|
||||
<span class="hljs-attribute">add</span>: <span class="hljs-function"><span class="hljs-params">(column, [sourceLine, sourceColumn], options={})</span> -></span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@columns</span>[column] <span class="hljs-keyword">and</span> options.noReplace
|
||||
<span class="hljs-property">@columns</span>[column] = {<span class="hljs-attribute">line</span>: <span class="hljs-property">@line</span>, column, sourceLine, sourceColumn}
|
||||
|
||||
<span class="hljs-attribute">sourceLocation</span>: <span class="hljs-function"><span class="hljs-params">(column)</span> -></span>
|
||||
column-- <span class="hljs-keyword">until</span> (mapping = <span class="hljs-property">@columns</span>[column]) <span class="hljs-keyword">or</span> (column <= <span class="hljs-number">0</span>)
|
||||
mapping <span class="hljs-keyword">and</span> [mapping.sourceLine, mapping.sourceColumn]</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-3">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<h2>LineMap</h2>
|
||||
<h2 id="sourcemap">SourceMap</h2>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -156,9 +175,18 @@ of this information — to write out alongside the generated JavaScript.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Maps locations in a single generated JavaScript file back to locations in
|
||||
the original CoffeeScript source file.</p>
|
||||
<p>This is intentionally agnostic towards how a source map might be represented on
|
||||
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
|
||||
through the arrays of line and column buffer to produce it.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SourceMap</span></span>
|
||||
<span class="hljs-attribute">constructor</span>:<span class="hljs-function"> -></span>
|
||||
<span class="hljs-property">@lines</span> = []</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -168,25 +196,17 @@ of this information — to write out alongside the generated JavaScript.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>A <strong>LineMap</strong> object keeps track of information about original line and column
|
||||
positions for a single line of output JavaScript code.
|
||||
<strong>SourceMaps</strong> are implemented in terms of <strong>LineMaps</strong>.
|
||||
</p>
|
||||
<p>Adds a mapping to this SourceMap. <code>sourceLocation</code> and <code>generatedLocation</code>
|
||||
are both <code>[line, column]</code> arrays. If <code>options.noReplace</code> is true, then if there
|
||||
is already a mapping for the specified <code>line</code> and <code>column</code>, this will have no
|
||||
effect.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
<span class="class"><span class="keyword">class</span> <span class="title">LineMap</span></span>
|
||||
constructor: (<span class="property">@line</span>) ->
|
||||
<span class="property">@columns</span> = []
|
||||
|
||||
add: (column, [sourceLine, sourceColumn], options={}) ->
|
||||
<span class="keyword">return</span> <span class="keyword">if</span> <span class="property">@columns</span>[column] <span class="keyword">and</span> options.noReplace
|
||||
<span class="property">@columns</span>[column] = {line: <span class="property">@line</span>, column, sourceLine, sourceColumn}
|
||||
|
||||
sourceLocation: (column) ->
|
||||
column-- <span class="keyword">until</span> (mapping = <span class="property">@columns</span>[column]) <span class="keyword">or</span> (column <= <span class="number">0</span>)
|
||||
mapping <span class="keyword">and</span> [mapping.sourceLine, mapping.sourceColumn]</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">add</span>: <span class="hljs-function"><span class="hljs-params">(sourceLocation, generatedLocation, options = {})</span> -></span>
|
||||
[line, column] = generatedLocation
|
||||
lineMap = (<span class="hljs-property">@lines</span>[line] <span class="hljs-keyword">or</span>= <span class="hljs-keyword">new</span> LineMap(line))
|
||||
lineMap.add column, sourceLocation, options</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -194,13 +214,18 @@ positions for a single line of output JavaScript code.
|
|||
<li id="section-6">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<h2>SourceMap</h2>
|
||||
<p>Look up the original position of a given <code>line</code> and <code>column</code> in the generated
|
||||
code.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">sourceLocation</span>: <span class="hljs-function"><span class="hljs-params">([line, column])</span> -></span>
|
||||
line-- <span class="hljs-keyword">until</span> (lineMap = <span class="hljs-property">@lines</span>[line]) <span class="hljs-keyword">or</span> (line <= <span class="hljs-number">0</span>)
|
||||
lineMap <span class="hljs-keyword">and</span> lineMap.sourceLocation column</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -210,6 +235,7 @@ positions for a single line of output JavaScript code.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<h2 id="v3-sourcemap-generation">V3 SourceMap Generation</h2>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -222,12 +248,29 @@ positions for a single line of output JavaScript code.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Maps locations in a single generated JavaScript file back to locations in
|
||||
the original CoffeeScript source file.
|
||||
</p>
|
||||
<p>Builds up a V3 source map, returning the generated JSON as a string.
|
||||
<code>options.sourceRoot</code> may be used to specify the sourceRoot written to the source
|
||||
map. Also, <code>options.sourceFiles</code> and <code>options.generatedFile</code> may be passed to
|
||||
set "sources" and "file", respectively.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">generate</span>: <span class="hljs-function"><span class="hljs-params">(options = {}, code = <span class="hljs-literal">null</span>)</span> -></span>
|
||||
writingline = <span class="hljs-number">0</span>
|
||||
lastColumn = <span class="hljs-number">0</span>
|
||||
lastSourceLine = <span class="hljs-number">0</span>
|
||||
lastSourceColumn = <span class="hljs-number">0</span>
|
||||
needComma = <span class="hljs-literal">no</span>
|
||||
buffer = <span class="hljs-string">""</span>
|
||||
|
||||
<span class="hljs-keyword">for</span> lineMap, lineNumber <span class="hljs-keyword">in</span> <span class="hljs-property">@lines</span> <span class="hljs-keyword">when</span> lineMap
|
||||
<span class="hljs-keyword">for</span> mapping <span class="hljs-keyword">in</span> lineMap.columns <span class="hljs-keyword">when</span> mapping
|
||||
<span class="hljs-keyword">while</span> writingline < mapping.line
|
||||
lastColumn = <span class="hljs-number">0</span>
|
||||
needComma = <span class="hljs-literal">no</span>
|
||||
buffer += <span class="hljs-string">";"</span>
|
||||
writingline++</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -237,17 +280,13 @@ the original CoffeeScript source file.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>This is intentionally agnostic towards how a source map might be represented on
|
||||
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
|
||||
through the arrays of line and column buffer to produce it.
|
||||
</p>
|
||||
<p>Write a comma if we've already written a segment on this line.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
<span class="class"><span class="keyword">class</span> <span class="title">SourceMap</span></span>
|
||||
constructor: ->
|
||||
<span class="property">@lines</span> = []</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needComma
|
||||
buffer += <span class="hljs-string">","</span>
|
||||
needComma = <span class="hljs-literal">no</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -258,19 +297,15 @@ through the arrays of line and column buffer to produce it.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Adds a mapping to this SourceMap. <code>sourceLocation</code> and <code>generatedLocation</code>
|
||||
are both <code>[line, column]</code> arrays. If <code>options.noReplace</code> is true, then if there
|
||||
is already a mapping for the specified <code>line</code> and <code>column</code>, this will have no
|
||||
effect.
|
||||
</p>
|
||||
<p>Write the next segment. Segments can be 1, 4, or 5 values. If just one, then it
|
||||
is a generated column which doesn't match anything in the source code.</p>
|
||||
<p>The starting column in the generated source, relative to any previous recorded
|
||||
column for the current line:</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
add: (sourceLocation, generatedLocation, options = {}) ->
|
||||
[line, column] = generatedLocation
|
||||
lineMap = (<span class="property">@lines</span>[line] <span class="keyword">or</span>= <span class="keyword">new</span> LineMap(line))
|
||||
lineMap.add column, sourceLocation, options</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> buffer += <span class="hljs-property">@encodeVlq</span> mapping.column - lastColumn
|
||||
lastColumn = mapping.column</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -281,16 +316,11 @@ effect.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Look up the original position of a given <code>line</code> and <code>column</code> in the generated
|
||||
code.
|
||||
</p>
|
||||
<p>The index into the list of sources:</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
sourceLocation: ([line, column]) ->
|
||||
line-- <span class="keyword">until</span> (lineMap = <span class="property">@lines</span>[line]) <span class="keyword">or</span> (line <= <span class="number">0</span>)
|
||||
lineMap <span class="keyword">and</span> lineMap.sourceLocation column</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> buffer += <span class="hljs-property">@encodeVlq</span> <span class="hljs-number">0</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -298,13 +328,16 @@ code.
|
|||
<li id="section-12">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<h2>V3 SourceMap Generation</h2>
|
||||
<p>The starting line in the original source, relative to the previous source line.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> buffer += <span class="hljs-property">@encodeVlq</span> mapping.sourceLine - lastSourceLine
|
||||
lastSourceLine = mapping.sourceLine</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -314,9 +347,14 @@ code.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>The starting column in the original source, relative to the previous column.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> buffer += <span class="hljs-property">@encodeVlq</span> mapping.sourceColumn - lastSourceColumn
|
||||
lastSourceColumn = mapping.sourceColumn
|
||||
needComma = <span class="hljs-literal">yes</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -326,30 +364,21 @@ code.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Builds up a V3 source map, returning the generated JSON as a string.
|
||||
<code>options.sourceRoot</code> may be used to specify the sourceRoot written to the source
|
||||
map. Also, <code>options.sourceFiles</code> and <code>options.generatedFile</code> may be passed to
|
||||
set "sources" and "file", respectively.
|
||||
</p>
|
||||
<p>Produce the canonical JSON object format for a "v3" source map.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
generate: (options = {}, code = <span class="literal">null</span>) ->
|
||||
writingline = <span class="number">0</span>
|
||||
lastColumn = <span class="number">0</span>
|
||||
lastSourceLine = <span class="number">0</span>
|
||||
lastSourceColumn = <span class="number">0</span>
|
||||
needComma = <span class="literal">no</span>
|
||||
buffer = <span class="string">""</span>
|
||||
<div class="content"><div class='highlight'><pre> v3 =
|
||||
<span class="hljs-attribute">version</span>: <span class="hljs-number">3</span>
|
||||
<span class="hljs-attribute">file</span>: options.generatedFile <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
||||
<span class="hljs-attribute">sourceRoot</span>: options.sourceRoot <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
||||
<span class="hljs-attribute">sources</span>: options.sourceFiles <span class="hljs-keyword">or</span> [<span class="hljs-string">''</span>]
|
||||
<span class="hljs-attribute">names</span>: []
|
||||
<span class="hljs-attribute">mappings</span>: buffer
|
||||
|
||||
<span class="keyword">for</span> lineMap, lineNumber <span class="keyword">in</span> <span class="property">@lines</span> <span class="keyword">when</span> lineMap
|
||||
<span class="keyword">for</span> mapping <span class="keyword">in</span> lineMap.columns <span class="keyword">when</span> mapping
|
||||
<span class="keyword">while</span> writingline < mapping.line
|
||||
lastColumn = <span class="number">0</span>
|
||||
needComma = <span class="literal">no</span>
|
||||
buffer += <span class="string">";"</span>
|
||||
writingline++</pre></div></div>
|
||||
v3.sourcesContent = [code] <span class="hljs-keyword">if</span> options.inline
|
||||
|
||||
JSON.stringify v3, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -360,16 +389,10 @@ set "sources" and "file", respectively.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>Write a comma if we've already written a segment on this line.
|
||||
</p>
|
||||
<h2 id="base64-vlq-encoding">Base64 VLQ Encoding</h2>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
<span class="keyword">if</span> needComma
|
||||
buffer += <span class="string">","</span>
|
||||
needComma = <span class="literal">no</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -379,12 +402,21 @@ set "sources" and "file", respectively.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>Write the next segment. Segments can be 1, 4, or 5 values. If just one, then it
|
||||
is a generated column which doesn't match anything in the source code.
|
||||
</p>
|
||||
<p>Note that SourceMap VLQ encoding is "backwards". MIDI-style VLQ encoding puts
|
||||
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
|
||||
encoded value (see <a href="http://en.wikipedia.org/wiki/File:Uintvar_coding.svg">Wikipedia</a>).
|
||||
SourceMap VLQ does things the other way around, with the least significat four
|
||||
bits of the original value encoded into the first byte of the VLQ encoded value.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> VLQ_SHIFT = <span class="hljs-number">5</span>
|
||||
VLQ_CONTINUATION_BIT = <span class="hljs-number">1</span> << VLQ_SHIFT <span class="hljs-comment"># 0010 0000</span>
|
||||
VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - <span class="hljs-number">1</span> <span class="hljs-comment"># 0001 1111</span>
|
||||
|
||||
<span class="hljs-attribute">encodeVlq</span>: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
||||
answer = <span class="hljs-string">''</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -394,15 +426,11 @@ is a generated column which doesn't match anything in the source code.
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>The starting column in the generated source, relative to any previous recorded
|
||||
column for the current line:
|
||||
</p>
|
||||
<p>Least significant bit represents the sign.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
buffer += <span class="property">@encodeVlq</span> mapping.column - lastColumn
|
||||
lastColumn = mapping.column</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> signBit = <span class="hljs-keyword">if</span> value < <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-number">0</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -413,13 +441,11 @@ column for the current line:
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>The index into the list of sources:
|
||||
</p>
|
||||
<p>The next bits are the actual value.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
buffer += <span class="property">@encodeVlq</span> <span class="number">0</span></pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> valueToEncode = (Math.abs(value) << <span class="hljs-number">1</span>) + signBit</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -430,14 +456,17 @@ column for the current line:
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>The starting line in the original source, relative to the previous source line.
|
||||
</p>
|
||||
<p>Make sure we encode at least one character, even if valueToEncode is 0.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
buffer += <span class="property">@encodeVlq</span> mapping.sourceLine - lastSourceLine
|
||||
lastSourceLine = mapping.sourceLine</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> valueToEncode <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> answer
|
||||
nextChunk = valueToEncode & VLQ_VALUE_MASK
|
||||
valueToEncode = valueToEncode >> VLQ_SHIFT
|
||||
nextChunk |= VLQ_CONTINUATION_BIT <span class="hljs-keyword">if</span> valueToEncode
|
||||
answer += <span class="hljs-property">@encodeBase64</span> nextChunk
|
||||
|
||||
answer</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -448,16 +477,10 @@ column for the current line:
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>The starting column in the original source, relative to the previous column.
|
||||
</p>
|
||||
<h2 id="regular-base64-encoding">Regular Base64 Encoding</h2>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
buffer += <span class="property">@encodeVlq</span> mapping.sourceColumn - lastSourceColumn
|
||||
lastSourceColumn = mapping.sourceColumn
|
||||
needComma = <span class="literal">yes</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
|
@ -467,23 +490,13 @@ column for the current line:
|
|||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>Produce the canonical JSON object format for a "v3" source map.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
v3 =
|
||||
version: <span class="number">3</span>
|
||||
file: options.generatedFile <span class="keyword">or</span> <span class="string">''</span>
|
||||
sourceRoot: options.sourceRoot <span class="keyword">or</span> <span class="string">''</span>
|
||||
sources: options.sourceFiles <span class="keyword">or</span> [<span class="string">''</span>]
|
||||
names: []
|
||||
mappings: buffer
|
||||
<div class="content"><div class='highlight'><pre> BASE64_CHARS = <span class="hljs-string">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'</span>
|
||||
|
||||
v3.sourcesContent = [code] <span class="keyword">if</span> options.inline
|
||||
|
||||
JSON.stringify v3, <span class="literal">null</span>, <span class="number">2</span></pre></div></div>
|
||||
<span class="hljs-attribute">encodeBase64</span>: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
||||
BASE64_CHARS[value] <span class="hljs-keyword">or</span> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Cannot Base64 encode value: <span class="hljs-subst">#{value}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
@ -491,152 +504,14 @@ column for the current line:
|
|||
<li id="section-22">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-22">¶</a>
|
||||
</div>
|
||||
<h2>Base64 VLQ Encoding</h2>
|
||||
<p>Our API for source maps is just the <code>SourceMap</code> class.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-23">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-23">¶</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-24">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-24">¶</a>
|
||||
</div>
|
||||
<p>Note that SourceMap VLQ encoding is "backwards". MIDI-style VLQ encoding puts
|
||||
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
|
||||
encoded value (see <a href="http://en.wikipedia.org/wiki/File:Uintvar_coding.svg">Wikipedia</a>).
|
||||
SourceMap VLQ does things the other way around, with the least significat four
|
||||
bits of the original value encoded into the first byte of the VLQ encoded value.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
VLQ_SHIFT = <span class="number">5</span>
|
||||
VLQ_CONTINUATION_BIT = <span class="number">1</span> << VLQ_SHIFT <span class="comment"># 0010 0000</span>
|
||||
VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - <span class="number">1</span> <span class="comment"># 0001 1111</span>
|
||||
|
||||
encodeVlq: (value) ->
|
||||
answer = <span class="string">''</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-25">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-25">¶</a>
|
||||
</div>
|
||||
<p>Least significant bit represents the sign.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> signBit = <span class="keyword">if</span> value < <span class="number">0</span> <span class="keyword">then</span> <span class="number">1</span> <span class="keyword">else</span> <span class="number">0</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-26">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-26">¶</a>
|
||||
</div>
|
||||
<p>The next bits are the actual value.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> valueToEncode = (Math.abs(value) << <span class="number">1</span>) + signBit</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-27">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-27">¶</a>
|
||||
</div>
|
||||
<p>Make sure we encode at least one character, even if valueToEncode is 0.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">while</span> valueToEncode <span class="keyword">or</span> <span class="keyword">not</span> answer
|
||||
nextChunk = valueToEncode & VLQ_VALUE_MASK
|
||||
valueToEncode = valueToEncode >> VLQ_SHIFT
|
||||
nextChunk |= VLQ_CONTINUATION_BIT <span class="keyword">if</span> valueToEncode
|
||||
answer += <span class="property">@encodeBase64</span> nextChunk
|
||||
|
||||
answer</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-28">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<a class="pilcrow" href="#section-28">¶</a>
|
||||
</div>
|
||||
<h2>Regular Base64 Encoding</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-29">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-29">¶</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
BASE64_CHARS = <span class="string">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'</span>
|
||||
|
||||
encodeBase64: (value) ->
|
||||
BASE64_CHARS[value] <span class="keyword">or</span> <span class="keyword">throw</span> <span class="keyword">new</span> Error <span class="string">"Cannot Base64 encode value: <span class="subst">#{value}</span>"</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-30">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-30">¶</a>
|
||||
</div>
|
||||
<p>Our API for source maps is just the <code>SourceMap</code> class.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
module.exports = SourceMap</pre></div></div>
|
||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.<span class="hljs-built_in">exports</span> = SourceMap</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue