The commas separating these three keywords are not code themselves – not what the user would write – so they should be outside of the `<tt>` tags.
Edits the table in the section [Operators and Aliases](http://coffeescript.org/#operators).
* Move all source path filtering to `compilePath`
* Restrict modification of `sources` to
* `compilePath` for adding
* `removeSource` for removing
* Don't add unfiltered paths to `sources` (and remove them later on)
* Use absolute paths for source files and target paths
* Memorize and explicitly check for watched directories
* Make path comparison and construction more precise and clear
* Remove now unnecessary check for special relative paths
* Break up `Closure` and merge `Closure.wrap` into `Base.compileClosure`
* Construct class closure directly in `Class.compileNode`
* Reuse `isLiteralArguments` in `Range.compileArray`
* Move all helpers to bottom of file
* Add test for #3063
* Resolves#3059: Don't remove escaped whitespace.
* Fixes#2238: Prevent escaping slashes that are already escaped.
* Fix detection of end of heregex with escaped slashes.
Add a new cli option: -g --polling [SPAN]
If state polling mode is enabled, use it.
Else use the native api.
This is useful while watching remote directory.
Such as the `fs.watch` won't catch the SMB server's file change event.
Make the REPL *CLI* use the global context so as to (a) be consistent
with the `node` REPL CLI and, therefore, (b) make packages that modify
native prototypes (such as 'colors' and 'sugar') work as expected.
Note that, by contrast, programmatic use (`require 'repl'`) will
continue to default to a NON-global context - again, consistent with
node's behavior.
Make the REPL *CLI* use the global context so as to (a) be consistent
with the `node` REPL CLI and, therefore, (b) make packages that modify
native prototypes (such as 'colors' and 'sugar') work as expected.
Note that, by contrast, programmatic use (`require 'repl'`) will
continue to default to a NON-global context - again, consistent with
node's behavior.
Note that, at least for now, CoffeeScript's own REPL *CLI* still uses a
non-global context, rendering modules such as `color`, which attempt to
modify the prototypes of JavaScript primitives, ineffective. By
contrast, node's own CLI does use the global context.
(My apologies: In the previous commit I accidentally made `useGlobal:
yes` the default for _programmatic_ use also, but the intent was to
only do it for the stand-alone *CLI*.)
Make the REPL *CLI* use the global context so as to (a) be consistent
with the `node` REPL CLI and, therefore, (b) make packages that modify
native prototypes (such as 'colors' and 'sugar') work as expected.
Note that, by contrast, programmatic use (`require 'repl'`) will
continue to default to a NON-global context - again, consistent with
node's behavior.
This will make packages that modify prototypes - e.g. 'colors', 'sugar'
- work as expected.
To verify that the `node` REPL uses the global context, execute `global
=== module.exports.repl.context`.
Note: Tests pass, except `cluster.coffee`, which, however, failed even
before these modifications.
This solves two potential problems when it comes to forking:
1) Forking will now work correctly even when `coffee` is not installed
globally.
2) Forking when using a locally installed version of `coffee` will fork
using that version, and not fallback to a globally installed version.
Fixes#2957
This makes the "stack" property more useful when it's shown on other Node.js applications that compile CoffeeScript (e.g. testing libraries) and should fix#3023. A minimal example:
$ node -e 'require("coffee-script").compile("class class")'
/usr/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:41
throw err;
^
[stdin]:1:7: error: unexpected CLASS
class class
^^^^^
Instead of throwing the syntax errors with their source file location and needing to then catch them and call a `prettyErrorMessage` function in order to get the formatted error message, now syntax errors know how to pretty-print themselves (their `toString` method gets overridden).
An intermediate `catch` & re-`throw` is needed at the level of `CoffeeScript.compile` and friends. But the benefit of this approach is that now libraries that use the `CoffeeScript` object directly don't need to bother catching the possible compilation errors and calling a special function in order to get the nice error messages; they can just print the error itself (or let it bubble up) and the error will know how to pretty-print itself.
* Supplement missing block before `ELSE` token only for multi-line `if`.
* Don't prematurely remove `TERMINATOR` before `ELSE` (so we can differentiate single- and multi-line forms).
* Cleanup: Remove `WHEN` from `EXPRESSION_CLOSE`. (Only `LEADING_WHEN` tokens are preceded by a `TERMINATOR`.)
* Cleanup: Remove really old, inapplicable text from comment.
In #3031, an extensions variable was introduced with file-level scope
that defined the filetypes that CoffeeScript can compile. However, the
Module::load patching calls findExtension() which uses a local variable
called "extensions", which was overriding the outer level one and
causing getSourceMap() to fail.
Example: if compilation invoked like this: 'coffee -o ../lib/ -cw ./', then
Source file: ./OutputFolder/file.coffee, compiled output: ./../lib/tputFolder/
The code only expected '.' to mark the local folder. However, './' is equally valid.
The history file was set to close on process exit, when it
should close on REPL exit. Listening to the process exit
event causes a warning when more than 10 CoffeeScript REPL
instances are opened in the same program, which happens in
the test.
* Expect a blank line as delimiter between text and code (#2821).
* Don't change indentation of code. It is not necessary and leads to
erroneous locationData. (#2835)
* Don't modify blank lines and reverse the change in the lexer.
* Don't ignore indentation with mixed whitespace.
remove unnecessary parens and else statement in repl
we do this by convention of the main coffee source
fix: exit should be process.exit
compiled and build full
Before:
coffee> foo = (bar, baz, bar, qux) ->
repl:1:7: error: multiple parameters named 'bar'
foo = (bar, baz, bar, qux) ->
^^^^^^^^^^^^^^^^^^^^^^^
Now:
coffee> foo = (bar, baz, bar, qux) ->
repl:1:18: error: multiple parameters named 'bar'
foo = (bar, baz, bar, qux) ->
^^^
Also works with destructuring parameters and what have you.
Nothing really fancy here; mostly preserves the old format. Maybe if we had a more full-fledged test editor we could show the errors in-line =D
Also, i couldn't get the `rake doc` task running properly, so i mostly test this editing the index.html directly (ups!).
These are the modifications I had to do in order to get source maps working
in 27.0.1425.2 (Official Build 185250) canary. I haven't tested other
browsers.
I first looked at the V3 spec and a few examples, and I saw that the
`source` key of the source map should be called `sources`.
After doing the `source` to `sources` change, the coffee source and for
some odd reason the javascript file would not show up in the browser
dev tools (it was being fetched but not evaluated).
To fix this, I had to add the coffee source to the `sources` list in the
source map file.
Move filename processing to a `parseFileName` function in
helpers.coffee.
Map `.coffee.md` as a Literate CoffeeScript extension.
Also, make .litcoffee and .coffee.md files executable without their file
extension - eg. `coffee test` would work for a file called
`test.litcoffee`.
Since the move to the nodeREPL package, input lines to be evaluated are
now wrapped in parentheses; that is:
'foo'
would become:
('foo'
)
The old way of detecting empty lines was to see if the input string was
either totally empty, or whitespace-only. The addition of these
parentheses breaks that.
In order to fix this, we simply tweak the regex a little to ignore these
added parentheses if they're present. As an added bonus, the regex
should match empty inputs even if they aren't.
This also makes the "empty command evaluates to undefined" test pass,
for the right reasons (i.e. not because of the broken error behavior
from before).
Compatibility is kept for path.exists. Versions of node that have
made the change will use fs.exists, while older versions will fall
back to path.exists. The same goes for path.existsSync.
The readline interface of node has changed in [aad12d0][] and because of
that the autocompletion and key movement didn't work anymore. This
commit fixes this by checking whether stdin is in raw mode (i.e. invoked
as a script) or not (as a repl).
[aad12d0]: https://github.com/joyent/node/commit/aad12d0
8bc6001d27 removed autocompletions of
non-enumerable own-properties in trying to add enumerable prototype
properties to the autocompletions. This commit adds them back and unions
them with the enumerable prototype properties.
case to show it's required.
What's going on: inside of Coffee-generated closures, calling `super()`
is implicitly making use of `this` (or explicitly doing so if you look
at the output code), so we have to pass `this` through closures as if
`@` is being accessed within the closure. So, just add one more
condition to the list in `Closure::literalThis`
Currently, the only mention of heregexes' support for interpolation is
in the change log. This feature is useful enough to warrant a mention in
the heregex section itself.
I also felt that the heregex section was a bit less clear than it could
be, so I slightly reworded it.
Make REPL continuation work better. Check for trailing "\" fails when
run function is called with buffer terminated by newline. Chomp'ing
buffer to remove newline fixes this issue.
The ultraviolet gem doesn't work with Ruby 1.9, instead
we need to use the updated 'spox' versions of ultraviolet
and plist:
spox-ultraviolet, spox-plist
This new rake task: install_coffeescript_syntax loads
either the original gems if running Ruby < 1.9 or the
'spox' versions if running on Ruby >= 1.9.
Load CoffeeScript.tmLanguage directly from the github repo
for the TextMate bundle.
Parse and write the yaml-format syntax file directly
into the correct location in the ultraviolet gem.
This is only slightly problematic for the most pathological of cases
where a prelude is followed by a set of statements, none of which
generate top-level variables or attempt to return. In these cases, the
non-prelude statements will be indented. See related discussion at
e4b3e838e2.
This pleasently surprised but also confused me when it worked. Now it's
documented. No example (yet), alas, but better than nothing.
Originally added in/around 07e66dd2.
This confused me every time I Ctrl+F'ed the home page for "index" and only got
this cryptic statement:
"Comprehensions replace (and compile into) for loops, with optional guard clauses
and the value of the current array index."
Now I can see how the index is used in the code.
While recursively traversing a source directory, if a directory was encountered containing either no .coffee files (ex. an .svn metadata directory) or where the last file processed in that directory was not a .coffee file, compileJoin() might never be called.
This issue was originally introduced by a (well-needed) optimization in commit dc272a680b.
In join mode, anytime the 'unprocessed' count is decremented, the remaining file count should be evaluated to determine if it is time to run compileJoin(). Previously, compileJoin() would only ever be called in one of the four possible terminating branches of this recursive asynchronous operation.
CoffeeScript.eval. Instead of writing about all the changes and why I
made those decisions, I'll just answer any questions in the commit
comments, so add a commit comment if you want to question anything.
Thanks to @TrevorBurnham and @satyr for their help/contributions. Also,
closes#1487. And still no REPL tests...
CoffeeScript.eval. Instead of writing about all the changes and why I
made those decisions, I'll just answer any questions in the commit
comments, so add a commit comment if you want to question anything.
Thanks to @TrevorBurnham and @satyr for their help/contributions. Also,
closes#1487. And still no REPL tests...
Here's how the algorithm in balancedString() was modified. When we
encounter a slash in an interpolation, we:
* try to find a heregex right after it; if found---skip it. Three
slashes always terminate a heregex, no matter if there is an open
"#{" before them or not, so we don't have to bother about
sub-interpolations inside the heregex.
* try to find a regex right after it; if found---skip it. Simple
regexen can't contain interpolations.
* otherwise, assume that the slash means division and carry on.
x = 10
([x]) -> # used to not declare var x
this is one fix, the other way to fix
it is to remove the entire if ... olen is 1 ....
block... not sure if that's a good idea or not.
*why* `require` and only `require` was affected. All other globals that
I tried were unaffected: `console`, `parseInt`, `process`, `global`,
`Array`, `Object`, `Buffer`, `setTimeout`, ...
"[v] = a ? b" must compile to
v = (typeof a != "undefined" && a !== null ? a : b)[0];
and not to:
v = typeof a != "undefined" && a !== null ? a : b[0];
Check the readline.createInterface for arity. If it is 3,
assume the newer interface requiring separate stdin and stdout.
Otherwise, use the older calling style.
This change allows files to be `--require`d before entering the REPL. It's also
an opimization, since files are `--require`d only once, rather than being
required again every time a file is compiled.
A secondary change is that `module.filename` is temporarily modified. This is
somewhat less aesthetically appealing than the old approach of using
fs.realpathSync, but it allows you to run `coffee -r ./foo` rather than having
to write `coffee -r ./foo.coffee`, since Node does not accept absolute paths
without a file extension.
See the tests added to test_comprehensions.coffee. Previously, after
`for i in [1..3]`, i was 4. Also, index variables were never set to
any value in comprehensions containing both a closure and a break or
return.
Allows `path.join` to do some processing on the base path
that was also happening on the full path.
Fixes: `coffee -o ./ ./`
Still broken: `coffee -o . .`
coffee -e -r ./snarl 'Hello!'
Contents of 'snarl.coffee' in the working directory:
http = require 'http'
CoffeeScript.on 'exception', (err) ->
client = http.createClient 9889, 'localhost'
request = client.request 'GET', '/?d={"action":1,"applicationName":"CoffeeScript","title":' + JSON.stringify(err.message) + ',"description":' + JSON.stringify(err.stack) + ',"priority":3}'
request.end()
err.handled = yes
To examine arguments available for each event (for debugging and getting started), use `puts JSON.stringify arguments`.
See http://nodejs.org/api.html#modules-309 and NODE_PATH for more details on how -r looks for files.
* Before you open a ticket or send a pull request, [search](https://github.com/jashkenas/coffee-script/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one.
* Before sending a pull request for a feature, be sure to have [tests](https://github.com/jashkenas/coffee-script/tree/master/test).
* Use the same coding style as the rest of the [codebase](https://github.com/jashkenas/coffee-script/tree/master/src). If you're just getting started with CoffeeScript, there's a nice [style guide](https://github.com/polarmobile/coffeescript-style-guide).
* In your pull request, do not add documentation to `index.html` or re-build the minified `coffee-script.js` file. We'll do those things before cutting a new release.
<spanclass="nv">CoffeeScript = </span><spanclass="nx">require</span><spanclass="s1">'./coffee-script'</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Keep track of the list of defined tasks, the accepted options, and so on.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">tasks = </span><spanclass="p">{}</span>
<spanclass="nv">oparse = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>Mixin the top-level Cake functions for Cakefiles to use directly.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">helpers</span><spanclass="p">.</span><spanclass="nx">extend</span><spanclass="nx">global</span><spanclass="p">,</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">task</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">description</span><spanclass="p">,</span><spanclass="nx">action</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">tasks</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="p">{</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">description</span><spanclass="p">,</span><spanclass="nx">action</span><spanclass="p">}</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">option</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">letter</span><spanclass="p">,</span><spanclass="nx">flag</span><spanclass="p">,</span><spanclass="nx">description</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">switches</span><spanclass="p">.</span><spanclass="nx">push</span><spanclass="p">[</span><spanclass="nx">letter</span><spanclass="p">,</span><spanclass="nx">flag</span><spanclass="p">,</span><spanclass="nx">description</span><spanclass="p">]</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</a></div><p>Invoke another task in the current Cakefile.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">invoke</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">tasks</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">].</span><spanclass="nx">action</span><spanclass="nx">options</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"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.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.run = </span><spanclass="o">-></span>
<spanclass="k">throw</span><spanclass="k">new</span><spanclass="nb">Error</span><spanclass="p">(</span><spanclass="s2">"Cakefile not found in #{process.cwd()}"</span><spanclass="p">)</span><spanclass="nx">unless</span><spanclass="nx">exists</span>
<spanclass="nx">invoke</span><spanclass="nx">arg</span><spanclass="k">for</span><spanclass="nx">arg</span><spanclass="k">in</span><spanclass="nx">options</span><spanclass="p">.</span><spanclass="nx">arguments</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>Display the list of Cake tasks in a format similar to <code>rake -T</code></p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">printTasks = </span><spanclass="o">-></span>
<spanclass="nx">puts</span><spanclass="nx">oparse</span><spanclass="p">.</span><spanclass="nx">help</span><spanclass="p">()</span><spanclass="k">if</span><spanclass="nx">switches</span><spanclass="p">.</span><spanclass="nx">length</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></div><p>Print an error and exit when attempting to all an undefined task.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">missingTask = </span><spanclass="p">(</span><spanclass="nx">task</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">puts</span><spanclass="s2">"No such task: \"#task\""</span>
<spanclass="keyword">return</span> cakefileDirectory parent <spanclass="keyword">unless</span> parent <spanclass="keyword">is</span> dir
<spanclass="keyword">throw</span><spanclass="keyword">new</span> Error <spanclass="string">"Cakefile not found in <spanclass="subst">#{process.cwd()}</span>"</span></pre></div></div>
<!DOCTYPE html><html><head><title>coffee-script.coffee</title><metahttp-equiv="content-type"content="text/html; charset=UTF-8"><linkrel="stylesheet"media="all"href="docco.css"/></head><body><divid="container"><divid="background"></div><divid="jump_to"> Jump To …<divid="jump_wrapper"><divid="jump_page"><aclass="source"href="cake.html"> cake.coffee </a><aclass="source"href="coffee-script.html"> coffee-script.coffee </a><aclass="source"href="command.html"> command.coffee </a><aclass="source"href="grammar.html"> grammar.coffee </a><aclass="source"href="helpers.html"> helpers.coffee </a><aclass="source"href="index.html"> index.coffee </a><aclass="source"href="lexer.html"> lexer.coffee </a><aclass="source"href="nodes.html"> nodes.coffee </a><aclass="source"href="optparse.html"> optparse.coffee </a><aclass="source"href="repl.html"> repl.coffee </a><aclass="source"href="rewriter.html"> rewriter.coffee </a><aclass="source"href="scope.html"> scope.coffee </a></div></div></div><tablecellpadding="0"cellspacing="0"><thead><tr><thclass="docs"><h1> coffee-script.coffee </h1></th><thclass="code"></th></tr></thead><tbody><trid="section-1"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-1">#</a></div><p>CoffeeScript can be used both on the server, as a command-line compiler based
on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
contains the main entry functions for tokenzing, parsing, and compiling source
CoffeeScript into JavaScript.</p>
<!DOCTYPE html>
<p>If included on a webpage, it will automatically sniff out, compile, and
execute all scripts present in <code>text/coffeescript</code> tags.</p></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Set up dependencies correctly for both the server and the browser.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">if</span><spanclass="nx">process</span><spanclass="o">?</span>
<spanclass="nv">helpers=</span><spanclass="k">this</span><spanclass="p">.</span><spanclass="nx">helpers</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>The current CoffeeScript version number.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.VERSION = </span><spanclass="s1">'0.9.0'</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>Instantiate a Lexer for our use here.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">lexer = </span><spanclass="k">new</span><spanclass="nx">Lexer</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
<spanclass="k">throw</span><spanclass="nx">err</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.tokens = </span><spanclass="p">(</span><spanclass="nx">code</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">lexer</span><spanclass="p">.</span><spanclass="nx">tokenize</span><spanclass="nx">code</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</a></div><p>Tokenize and parse a string of CoffeeScript code, and return the AST. You can
then compile it by calling <code>.compile()</code> on the root, or traverse it by using
<code>.traverse()</code> with a callback.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.nodes = </span><spanclass="p">(</span><spanclass="nx">code</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">parser</span><spanclass="p">.</span><spanclass="nx">parse</span><spanclass="nx">lexer</span><spanclass="p">.</span><spanclass="nx">tokenize</span><spanclass="nx">code</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.run = </span><spanclass="p">((</span><spanclass="nx">code</span><spanclass="p">,</span><spanclass="nx">options</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">)</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>The real Lexer produces a generic stream of tokens. This object provides a
<spanclass="nx">upcomingInput</span><spanclass="o">:</span><spanclass="o">-></span><spanclass="s2">""</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></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. Unfortunately, the text contents of remote scripts cannot be
accessed from the browser, so only inline script tags will work.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">if</span><spanclass="nb">document</span><spanclass="o">?</span><spanclass="o">and</span><spanclass="nb">document</span><spanclass="p">.</span><spanclass="nx">getElementsByTagName</span>
<p>Based on <ahref="http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js">http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js</a>
<spanclass="p">{</span><spanclass="nx">spawn</span><spanclass="p">,</span><spanclass="nx">exec</span><spanclass="p">}</span><spanclass="o">=</span><spanclass="nx">require</span><spanclass="s1">'child_process'</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>The help banner that is printed when <code>coffee</code> is called without arguments.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">BANNER = </span><spanclass="s1">'''</span>
<spanclass="s1"> coffee compiles CoffeeScript source files into JavaScript.</span>
<spanclass="s1">'''</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>The list of all the valid option flags that <code>coffee</code> knows how to handle.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">SWITCHES = </span><spanclass="p">[</span>
<spanclass="p">[</span><spanclass="s1">'-c'</span><spanclass="p">,</span><spanclass="s1">'--compile'</span><spanclass="p">,</span><spanclass="s1">'compile to JavaScript and save as .js files'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-i'</span><spanclass="p">,</span><spanclass="s1">'--interactive'</span><spanclass="p">,</span><spanclass="s1">'run an interactive CoffeeScript REPL'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-o'</span><spanclass="p">,</span><spanclass="s1">'--output [DIR]'</span><spanclass="p">,</span><spanclass="s1">'set the directory for compiled JavaScript'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-w'</span><spanclass="p">,</span><spanclass="s1">'--watch'</span><spanclass="p">,</span><spanclass="s1">'watch scripts for changes, and recompile'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-p'</span><spanclass="p">,</span><spanclass="s1">'--print'</span><spanclass="p">,</span><spanclass="s1">'print the compiled JavaScript to stdout'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-l'</span><spanclass="p">,</span><spanclass="s1">'--lint'</span><spanclass="p">,</span><spanclass="s1">'pipe the compiled JavaScript through JSLint'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-s'</span><spanclass="p">,</span><spanclass="s1">'--stdio'</span><spanclass="p">,</span><spanclass="s1">'listen for and compile scripts over stdio'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-e'</span><spanclass="p">,</span><spanclass="s1">'--eval'</span><spanclass="p">,</span><spanclass="s1">'compile a string from the command line'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'--no-wrap'</span><spanclass="p">,</span><spanclass="s1">'compile without the top-level function wrapper'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-t'</span><spanclass="p">,</span><spanclass="s1">'--tokens'</span><spanclass="p">,</span><spanclass="s1">'print the tokens that the lexer produces'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-n'</span><spanclass="p">,</span><spanclass="s1">'--nodes'</span><spanclass="p">,</span><spanclass="s1">'print the parse tree that Jison produces'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="s1">'-h'</span><spanclass="p">,</span><spanclass="s1">'--help'</span><spanclass="p">,</span><spanclass="s1">'display this help message'</span><spanclass="p">]</span>
<spanclass="p">]</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>Top-level objects shared by all the functions.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">options = </span><spanclass="p">{}</span>
<spanclass="nv">optionParser = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Run <code>coffee</code> by parsing passed options and determining what action to take.
[<spanclass="string">'-b'</span>, <spanclass="string">'--bare'</span>, <spanclass="string">'compile without a top-level function wrapper'</span>]
[<spanclass="string">'-c'</span>, <spanclass="string">'--compile'</span>, <spanclass="string">'compile to JavaScript and save as .js files'</span>]
[<spanclass="string">'-e'</span>, <spanclass="string">'--eval'</span>, <spanclass="string">'pass a string from the command line as input'</span>]
[<spanclass="string">'-h'</span>, <spanclass="string">'--help'</span>, <spanclass="string">'display this help message'</span>]
[<spanclass="string">'-i'</span>, <spanclass="string">'--interactive'</span>, <spanclass="string">'run an interactive CoffeeScript REPL'</span>]
[<spanclass="string">'-j'</span>, <spanclass="string">'--join [FILE]'</span>, <spanclass="string">'concatenate the source CoffeeScript before compiling'</span>]
[<spanclass="string">'-m'</span>, <spanclass="string">'--map'</span>, <spanclass="string">'generate source map and save as .map files'</span>]
[<spanclass="string">'-n'</span>, <spanclass="string">'--nodes'</span>, <spanclass="string">'print out the parse tree that the parser produces'</span>]
[ <spanclass="string">'--nodejs [ARGS]'</span>, <spanclass="string">'pass options directly to the "node" binary'</span>]
[<spanclass="string">'-o'</span>, <spanclass="string">'--output [DIR]'</span>, <spanclass="string">'set the output directory for compiled JavaScript'</span>]
[<spanclass="string">'-p'</span>, <spanclass="string">'--print'</span>, <spanclass="string">'print out the compiled JavaScript'</span>]
[<spanclass="string">'-s'</span>, <spanclass="string">'--stdio'</span>, <spanclass="string">'listen for and compile scripts over stdio'</span>]
[<spanclass="string">'-l'</span>, <spanclass="string">'--literate'</span>, <spanclass="string">'treat stdio as literate style coffee-script'</span>]
[<spanclass="string">'-t'</span>, <spanclass="string">'--tokens'</span>, <spanclass="string">'print out the tokens that the lexer/rewriter produce'</span>]
[<spanclass="string">'-v'</span>, <spanclass="string">'--version'</span>, <spanclass="string">'display the version number'</span>]
[<spanclass="string">'-w'</span>, <spanclass="string">'--watch'</span>, <spanclass="string">'watch scripts for changes and rerun commands'</span>]
<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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.run = </span><spanclass="o">-></span>
<spanclass="nx">compileScripts</span><spanclass="p">()</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</a></div><p>Asynchronously read in each CoffeeScript in a list of source files and
compile them. If a directory is passed, recursively compile all
'.coffee' extension source files in it and all subdirectories.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compileScripts = </span><spanclass="o">-></span>
<spanclass="k">throw</span><spanclass="k">new</span><spanclass="nb">Error</span><spanclass="s2">"File not found: #source"</span><spanclass="nx">unless</span><spanclass="nx">exists</span>
<spanclass="nx">compile</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="kc">true</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</a></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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compileScript = </span><spanclass="p">(</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="nx">code</span><spanclass="p">,</span><spanclass="nx">base</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">puts</span><spanclass="nx">err</span><spanclass="p">.</span><spanclass="nx">message</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
and write them back to <strong>stdout</strong>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compileStdio = </span><spanclass="o">-></span>
<spanclass="nx">compileScript</span><spanclass="s1">'stdio'</span><spanclass="p">,</span><spanclass="nx">code</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></div><p>Watch a source CoffeeScript file using <code>fs.watchFile</code>, recompiling it every
time the file is updated. May be used in combination with other options,
such as <code>--lint</code> or <code>--print</code>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">watch = </span><spanclass="p">(</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="nx">base</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">fs</span><spanclass="p">.</span><spanclass="nx">readFile</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="p">(</span><spanclass="nx">err</span><spanclass="p">,</span><spanclass="nx">code</span><spanclass="p">)</span><spanclass="o">-></span><spanclass="nx">compileScript</span><spanclass="p">(</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="nx">code</span><spanclass="p">.</span><spanclass="nx">toString</span><spanclass="p">(),</span><spanclass="nx">base</span><spanclass="p">)</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-11">#</a></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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">writeJs = </span><spanclass="p">(</span><spanclass="nx">source</span><spanclass="p">,</span><spanclass="nx">js</span><spanclass="p">,</span><spanclass="nx">base</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">if</span><spanclass="nx">exists</span><spanclass="k">then</span><spanclass="nx">compile</span><spanclass="p">()</span><spanclass="k">else</span><spanclass="nx">exec</span><spanclass="s2">"mkdir -p #dir"</span><spanclass="p">,</span><spanclass="nx">compile</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-12">#</a></div><p>Pipe compiled JS through JSLint (requires a working <code>jsl</code> command), printing
any errors or warnings that arise.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">lint = </span><spanclass="p">(</span><spanclass="nx">js</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">jsl</span><spanclass="p">.</span><spanclass="nx">stdin</span><spanclass="p">.</span><spanclass="nx">end</span><spanclass="p">()</span></pre></div></td></tr><trid="section-13"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-13">#</a></div><p>Pretty-print a stream of tokens.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">printTokens = </span><spanclass="p">(</span><spanclass="nx">tokens</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">puts</span><spanclass="nx">strings</span><spanclass="p">.</span><spanclass="nx">join</span><spanclass="p">(</span><spanclass="s1">''</span><spanclass="p">)</span></pre></div></td></tr><trid="section-14"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-14">#</a></div><p>Use the <ahref="optparse.html">OptionParser module</a> to extract all options from
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">parseOptions = </span><spanclass="o">-></span>
<spanclass="nv">sources = </span><spanclass="nx">options</span><spanclass="p">.</span><spanclass="nx">arguments</span></pre></div></td></tr><trid="section-15"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-15">#</a></div><p>The compile-time options to pass to the CoffeeScript compiler.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compileOptions = </span><spanclass="p">(</span><spanclass="nx">fileName</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">o</span></pre></div></td></tr><trid="section-16"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-16">#</a></div><p>Print the <code>--help</code> usage message and exit.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">usage = </span><spanclass="o">-></span>
<spanclass="nx">process</span><spanclass="p">.</span><spanclass="nx">exit</span><spanclass="mi">0</span></pre></div></td></tr><trid="section-17"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-17">#</a></div><p>Print the <code>--version</code> message and exit.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">version = </span><spanclass="o">-></span>
<spanclass="nx">puts</span><spanclass="s2">"CoffeeScript version #CoffeeScript.VERSION"</span>
<spanclass="keyword">return</span> printWarn <spanclass="string">"The --watch feature depends on Node v0.6.0+. You are running <spanclass="subst">#{process.version}</span>."</span>
<!DOCTYPE html><html><head><title>helpers.coffee</title><metahttp-equiv="content-type"content="text/html; charset=UTF-8"><linkrel="stylesheet"media="all"href="docco.css"/></head><body><divid="container"><divid="background"></div><divid="jump_to"> Jump To …<divid="jump_wrapper"><divid="jump_page"><aclass="source"href="cake.html"> cake.coffee </a><aclass="source"href="coffee-script.html"> coffee-script.coffee </a><aclass="source"href="command.html"> command.coffee </a><aclass="source"href="grammar.html"> grammar.coffee </a><aclass="source"href="helpers.html"> helpers.coffee </a><aclass="source"href="index.html"> index.coffee </a><aclass="source"href="lexer.html"> lexer.coffee </a><aclass="source"href="nodes.html"> nodes.coffee </a><aclass="source"href="optparse.html"> optparse.coffee </a><aclass="source"href="repl.html"> repl.coffee </a><aclass="source"href="rewriter.html"> rewriter.coffee </a><aclass="source"href="scope.html"> scope.coffee </a></div></div></div><tablecellpadding="0"cellspacing="0"><thead><tr><thclass="docs"><h1> helpers.coffee </h1></th><thclass="code"></th></tr></thead><tbody><trid="section-1"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-1">#</a></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></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">this</span><spanclass="p">.</span><spanclass="nv">exports = </span><spanclass="k">this</span><spanclass="nx">unless</span><spanclass="nx">process</span><spanclass="o">?</span>
<spanclass="nv">helpers = exports.helpers = </span><spanclass="p">{}</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Cross-browser indexOf, so that IE can join the party.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.indexOf = indexOf = </span><spanclass="p">(</span><spanclass="nx">array</span><spanclass="p">,</span><spanclass="nx">item</span><spanclass="p">,</span><spanclass="nx">from</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="o">-</span><spanclass="mi">1</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>Does a list include a value?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.include = include = </span><spanclass="p">(</span><spanclass="nx">list</span><spanclass="p">,</span><spanclass="nx">value</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">indexOf</span><spanclass="p">(</span><spanclass="nx">list</span><spanclass="p">,</span><spanclass="nx">value</span><spanclass="p">)</span><spanclass="o">>=</span><spanclass="mi">0</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>Peek at the beginning of a given string to see if it matches a sequence.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.starts = starts = </span><spanclass="p">(</span><spanclass="nx">string</span><spanclass="p">,</span><spanclass="nx">literal</span><spanclass="p">,</span><spanclass="nx">start</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">string</span><spanclass="p">.</span><spanclass="nx">substring</span><spanclass="p">(</span><spanclass="nx">start</span><spanclass="p">,</span><spanclass="p">(</span><spanclass="nx">start</span><spanclass="o">or</span><spanclass="mi">0</span><spanclass="p">)</span><spanclass="o">+</span><spanclass="nx">literal</span><spanclass="p">.</span><spanclass="nx">length</span><spanclass="p">)</span><spanclass="o">is</span><spanclass="nx">literal</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Peek at the end of a given string to see if it matches a sequence.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.ends = ends = </span><spanclass="p">(</span><spanclass="nx">string</span><spanclass="p">,</span><spanclass="nx">literal</span><spanclass="p">,</span><spanclass="nx">back</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">string</span><spanclass="p">.</span><spanclass="nx">substring</span><spanclass="p">(</span><spanclass="nx">start</span><spanclass="p">,</span><spanclass="nx">start</span><spanclass="o">+</span><spanclass="nx">literal</span><spanclass="p">.</span><spanclass="nx">length</span><spanclass="p">)</span><spanclass="o">is</span><spanclass="nx">literal</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</a></div><p>Trim out all falsy values from an array.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.compact = compact = </span><spanclass="p">(</span><spanclass="nx">array</span><spanclass="p">)</span><spanclass="o">-></span><spanclass="nx">item</span><spanclass="k">for</span><spanclass="nx">item</span><spanclass="k">in</span><spanclass="nx">array</span><spanclass="k">when</span><spanclass="nx">item</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</a></div><p>Count the number of occurences of a character in a string.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.count = count = </span><spanclass="p">(</span><spanclass="nx">string</span><spanclass="p">,</span><spanclass="nx">letter</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">num</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>Merge objects, returning a fresh copy with attributes from both sides.
Used every time <code>BaseNode#compile</code> is called, to allow properties in the
options hash to propagate down the tree without polluting other branches.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.merge = merge = </span><spanclass="p">(</span><spanclass="nx">options</span><spanclass="p">,</span><spanclass="nx">overrides</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">fresh</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></div><p>Extend a source object with the properties of another object (shallow copy).
We use this to simulate Node's deprecated <code>process.mixin</code></p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.extend = extend = </span><spanclass="p">(</span><spanclass="nx">object</span><spanclass="p">,</span><spanclass="nx">properties</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="nx">object</span><spanclass="p">[</span><spanclass="nx">key</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="nx">val</span><spanclass="p">)</span><spanclass="k">for</span><spanclass="nx">all</span><spanclass="nx">key</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="k">of</span><spanclass="nx">properties</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-11">#</a></div><p>Return a completely flattened version of an array. Handy for getting a
list of <code>children</code> from the nodes.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.flatten = flatten = </span><spanclass="p">(</span><spanclass="nx">array</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">memo</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-12">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">helpers.del = del = </span><spanclass="p">(</span><spanclass="nx">obj</span><spanclass="p">,</span><spanclass="nx">key</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="keyword">return</span><spanclass="literal">true</span><spanclass="keyword">for</span> e <spanclass="keyword">in</span><spanclass="keyword">this</span><spanclass="keyword">when</span> fn e
<aclass="large"href="javascript:void(0);">Jump To …</a>
<aclass="small"href="javascript:void(0);">+</a>
<divid="jump_wrapper">
<divid="jump_page">
<aclass="source"href="browser.html">
browser.coffee
</a>
<aclass="source"href="cake.html">
cake.coffee
</a>
<aclass="source"href="coffee-script.html">
coffee-script.coffee
</a>
<aclass="source"href="command.html">
command.coffee
</a>
<aclass="source"href="grammar.html">
grammar.coffee
</a>
<aclass="source"href="helpers.html">
helpers.coffee
</a>
<aclass="source"href="index.html">
index.coffee
</a>
<aclass="source"href="lexer.html">
lexer.coffee
</a>
<aclass="source"href="nodes.html">
nodes.coffee
</a>
<aclass="source"href="optparse.html">
optparse.coffee
</a>
<aclass="source"href="repl.html">
repl.coffee
</a>
<aclass="source"href="rewriter.html">
rewriter.coffee
</a>
<aclass="source"href="scope.html">
scope.litcoffee
</a>
<aclass="source"href="sourcemap.html">
sourcemap.litcoffee
</a>
</div>
</li>
</ul>
<ulclass="sections">
<liid="title">
<divclass="annotation">
<h1>index.coffee</h1>
</div>
</li>
<liid="section-1">
<divclass="annotation">
<divclass="pilwrap ">
<aclass="pilcrow"href="#section-1">¶</a>
</div>
<p>Loader for CoffeeScript as a Node.js library.
</p>
</div>
<divclass="content"><divclass='highlight'><pre>exports[key] = val <spanclass="keyword">for</span> key, val <spanclass="keyword">of</span> require <spanclass="string">'./coffee-script'</span></pre></div></div>
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
Use it like so:
</p>
<pre><code>parser = new OptionParser switches, helpBanner
options = parser.parse process.argv
</code></pre>
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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.OptionParser = </span><spanclass="nx">class</span><spanclass="nx">OptionParser</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Initialize with a list of valid options, in the form:</p>
option) list, and all subsequent arguments are left unparsed.
<p>Initialize with a list of valid options, in the form:
<p>Along with an an optional banner for the usage help.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">constructor</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">rules</span><spanclass="p">,</span><spanclass="nx">banner</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="vi">@rules = </span><spanclass="nx">buildRules</span><spanclass="nx">rules</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Parse the list of arguments, populating an <code>options</code> object with all of the
specified options, and returning it. <code>options.arguments</code> will be an array
containing the remaning non-option 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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">parse</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">args</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">options</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">help</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="nv">OPTIONAL = </span><spanclass="sr">/\[(.+)\]/</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">buildRules = </span><spanclass="p">(</span><spanclass="nx">rules</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">buildRule</span><spanclass="nx">tuple</span><spanclass="p">...</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">buildRule = </span><spanclass="p">(</span><spanclass="nx">shortFlag</span><spanclass="p">,</span><spanclass="nx">longFlag</span><spanclass="p">,</span><spanclass="nx">description</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">}</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">normalizeArguments = </span><spanclass="p">(</span><spanclass="nx">args</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="keyword">if</span> match = arg.match MULTI_FLAG
result.push <spanclass="string">'-'</span> + l <spanclass="keyword">for</span> l <spanclass="keyword">in</span> match[<spanclass="number">1</span>].split <spanclass="string">''</span>
<!DOCTYPE html><html><head><title>repl.coffee</title><metahttp-equiv="content-type"content="text/html; charset=UTF-8"><linkrel="stylesheet"media="all"href="docco.css"/></head><body><divid="container"><divid="background"></div><divid="jump_to"> Jump To …<divid="jump_wrapper"><divid="jump_page"><aclass="source"href="cake.html"> cake.coffee </a><aclass="source"href="coffee-script.html"> coffee-script.coffee </a><aclass="source"href="command.html"> command.coffee </a><aclass="source"href="grammar.html"> grammar.coffee </a><aclass="source"href="helpers.html"> helpers.coffee </a><aclass="source"href="index.html"> index.coffee </a><aclass="source"href="lexer.html"> lexer.coffee </a><aclass="source"href="nodes.html"> nodes.coffee </a><aclass="source"href="optparse.html"> optparse.coffee </a><aclass="source"href="repl.html"> repl.coffee </a><aclass="source"href="rewriter.html"> rewriter.coffee </a><aclass="source"href="scope.html"> scope.coffee </a></div></div></div><tablecellpadding="0"cellspacing="0"><thead><tr><thclass="docs"><h1> repl.coffee </h1></th><thclass="code"></th></tr></thead><tbody><trid="section-1"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-1">#</a></div><p>A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript
and evaluates it. Good for simple tests, or poking around the <strong>Node.js</strong> API.
Using it looks like this:</p>
<!DOCTYPE html>
<pre><code>coffee> puts "#num bottles of beer" for num in [99..1]
</code></pre></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Require the <strong>coffee-script</strong> module to get access to the compiler.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">CoffeeScript = </span><spanclass="nx">require</span><spanclass="s1">'./coffee-script'</span>
<spanclass="nv">readline = </span><spanclass="nx">require</span><spanclass="s1">'readline'</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Start by opening up <strong>stdio</strong>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">stdio = </span><spanclass="nx">process</span><spanclass="p">.</span><spanclass="nx">openStdin</span><spanclass="p">()</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>Quick alias for quitting the REPL.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">helpers</span><spanclass="p">.</span><spanclass="nx">extend</span><spanclass="nx">global</span><spanclass="p">,</span><spanclass="nx">quit</span><spanclass="o">:</span><spanclass="o">-></span><spanclass="nx">process</span><spanclass="p">.</span><spanclass="nx">exit</span><spanclass="p">(</span><spanclass="mi">0</span><spanclass="p">)</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>The main REPL function. <strong>run</strong> is called every time a line of code is entered.
Attempt to evaluate the command. If there's an exception, print it out instead
of exiting.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">run = </span><spanclass="p">(</span><spanclass="nx">buffer</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">repl</span><spanclass="p">.</span><spanclass="nx">prompt</span><spanclass="p">()</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Create the REPL by listening to <strong>stdin</strong>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">repl = </span><spanclass="nx">readline</span><spanclass="p">.</span><spanclass="nx">createInterface</span><spanclass="nx">stdio</span>
<spanclass="keyword">if</span> major <spanclass="keyword">is</span><spanclass="number">0</span><spanclass="keyword">and</span> minor <<spanclass="number">8</span>
console.warn <spanclass="string">"Node 0.8.0+ required for CoffeeScript REPL"</span>
<aclass="large"href="javascript:void(0);">Jump To …</a>
<aclass="small"href="javascript:void(0);">+</a>
<divid="jump_wrapper">
<divid="jump_page">
<aclass="source"href="browser.html">
browser.coffee
</a>
<aclass="source"href="cake.html">
cake.coffee
</a>
<aclass="source"href="coffee-script.html">
coffee-script.coffee
</a>
<aclass="source"href="command.html">
command.coffee
</a>
<aclass="source"href="grammar.html">
grammar.coffee
</a>
<aclass="source"href="helpers.html">
helpers.coffee
</a>
<aclass="source"href="index.html">
index.coffee
</a>
<aclass="source"href="lexer.html">
lexer.coffee
</a>
<aclass="source"href="nodes.html">
nodes.coffee
</a>
<aclass="source"href="optparse.html">
optparse.coffee
</a>
<aclass="source"href="repl.html">
repl.coffee
</a>
<aclass="source"href="rewriter.html">
rewriter.coffee
</a>
<aclass="source"href="scope.html">
scope.litcoffee
</a>
<aclass="source"href="sourcemap.html">
sourcemap.litcoffee
</a>
</div>
</li>
</ul>
<ulclass="sections">
<liid="title">
<divclass="annotation">
<h1>scope.litcoffee</h1>
</div>
</li>
<liid="section-1">
<divclass="annotation">
<divclass="pilwrap ">
<aclass="pilcrow"href="#section-1">¶</a>
</div>
<p>The <strong>Scope</strong> class regulates lexical scoping within CoffeeScript. As you
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 the outside.</p></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">this</span><spanclass="p">.</span><spanclass="nv">exports = </span><spanclass="k">this</span><spanclass="nx">unless</span><spanclass="nx">process</span><spanclass="o">?</span>
with external scopes.
</p>
<spanclass="nv">exports.Scope = </span><spanclass="nx">class</span><spanclass="nx">Scope</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>The top-level <strong>Scope</strong> object.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">@root</span><spanclass="o">:</span><spanclass="kc">null</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"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>Expressions</strong> node is belongs to, which is
<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 wraps.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">constructor</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">parent</span><spanclass="p">,</span><spanclass="nx">expressions</span><spanclass="p">,</span><spanclass="nx">method</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="vi">@tempVar = </span><spanclass="s1">'_a'</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>Look up a variable name in lexical scope, and declare it if it does not
<spanclass="kc">false</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Test variables and return true the first time fn(v, k) returns true</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">any</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">fn</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">return</span><spanclass="kc">false</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">parameter</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">@variables</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="s1">'param'</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</a></div><p>Just check to see if a variable has already been declared, without reserving.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">check</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="o">!!</span><spanclass="p">(</span><spanclass="nx">@parent</span><spanclass="o">and</span><spanclass="nx">@parent</span><spanclass="p">.</span><spanclass="nx">check</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">))</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_a</code>, <code>_b</code>, and so on...</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">freeVariable</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="nx">@tempVar</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></div><p>Ensure that an assignment is made at the top of this scope
(or at the top-level scope, if requested).</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">assign</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">value</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">@variables</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="nx">value</span><spanclass="o">:</span><spanclass="nx">value</span><spanclass="p">,</span><spanclass="nx">assigned</span><spanclass="o">:</span><spanclass="kc">true</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-11">#</a></div><p>Does this scope reference any variables that need to be declared in the
given function body?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">hasDeclarations</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">body</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">body</span><spanclass="o">is</span><spanclass="nx">@expressions</span><spanclass="o">and</span><spanclass="nx">@any</span><spanclass="p">(</span><spanclass="nx">k</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="p">)</span><spanclass="o">-></span><spanclass="nx">val</span><spanclass="o">is</span><spanclass="s1">'var'</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-12">#</a></div><p>Does this scope reference any assignments that need to be declared at the
top of the given function body?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">hasAssignments</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">body</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">body</span><spanclass="o">is</span><spanclass="nx">@expressions</span><spanclass="o">and</span><spanclass="nx">@any</span><spanclass="p">(</span><spanclass="nx">k</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="p">)</span><spanclass="o">-></span><spanclass="nx">val</span><spanclass="p">.</span><spanclass="nx">assigned</span></pre></div></td></tr><trid="section-13"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-13">#</a></div><p>Return the list of variables first declared in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">declaredVariables</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="nx">key</span><spanclass="k">for</span><spanclass="nx">key</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="k">of</span><spanclass="nx">@variables</span><spanclass="k">when</span><spanclass="nx">val</span><spanclass="o">is</span><spanclass="s1">'var'</span><spanclass="p">).</span><spanclass="nx">sort</span><spanclass="p">()</span></pre></div></td></tr><trid="section-14"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-14">#</a></div><p>Return the list of assignments that are supposed to be made at the top
of this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">assignedVariables</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="s2">"#key = #val.value"</span><spanclass="k">for</span><spanclass="nx">key</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="k">of</span><spanclass="nx">@variables</span><spanclass="k">when</span><spanclass="nx">val</span><spanclass="p">.</span><spanclass="nx">assigned</span></pre></div></td></tr><trid="section-15"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-15">#</a></div><p>Compile the JavaScript for all of the variable declarations in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">compiledDeclarations</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="nx">@declaredVariables</span><spanclass="p">().</span><spanclass="nx">join</span><spanclass="s1">', '</span></pre></div></td></tr><trid="section-16"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-16">#</a></div><p>Compile the JavaScript for all of the variable assignments in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">compiledAssignments</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="string">'_'</span> + name + <spanclass="keyword">if</span> index ><spanclass="number">1</span><spanclass="keyword">then</span> index - <spanclass="number">1</span><spanclass="keyword">else</span><spanclass="string">''</span>
<spanclass="keyword">return</span> v.type <spanclass="keyword">for</span> v <spanclass="keyword">in</span><spanclass="property">@variables</span><spanclass="keyword">when</span> v.name <spanclass="keyword">is</span> name
<p>Return the list of variables first declared in this scope.
</p>
</div>
<divclass="content"><divclass='highlight'><pre>
declaredVariables: ->
realVars = []
tempVars = []
<spanclass="keyword">for</span> v <spanclass="keyword">in</span><spanclass="property">@variables</span><spanclass="keyword">when</span> v.type <spanclass="keyword">is</span><spanclass="string">'var'</span>
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.