Compare commits

..

5 Commits
1.7.0 ... 1.6.2

Author SHA1 Message Date
Jeremy Ashkenas
3527af89fa new new docs 2013-03-13 11:48:23 +08:00
Jeremy Ashkenas
b32e3c0dfb fixing gray for github pages 2013-03-11 23:33:43 +08:00
Jeremy Ashkenas
956f432a68 fixing viewport 2013-03-11 22:21:22 +08:00
Jeremy Ashkenas
65d39c50f1 new docs, mo docs, shiny docs 2013-03-11 22:03:03 +08:00
Jeremy Ashkenas
55f60506b9 Fixes #2783 -- leftover comments 2013-03-06 07:14:37 +13:00
164 changed files with 9408 additions and 14162 deletions

View File

@@ -1,6 +1,5 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore'
CoffeeScript = require './lib/coffee-script'
{spawn, exec} = require 'child_process'
helpers = require './lib/coffee-script/helpers'
@@ -42,29 +41,6 @@ run = (args, cb) ->
log = (message, color, explanation) ->
console.log color + message + reset + ' ' + (explanation or '')
codeFor = ->
counter = 0
hljs = require 'highlight.js'
hljs.configure classPrefix: ''
(file, executable = false, showLoad = true) ->
counter++
return unless fs.existsSync "documentation/js/#{file}.js"
cs = fs.readFileSync "documentation/coffee/#{file}.coffee", 'utf-8'
js = fs.readFileSync "documentation/js/#{file}.js", 'utf-8'
js = js.replace /^\/\/ generated.*?\n/i, ''
cshtml = "<pre><code>#{hljs.highlight('coffeescript', cs).value}</code></pre>"
jshtml = "<pre><code>#{hljs.highlight('javascript', js).value}</code></pre>"
append = if executable is yes then '' else "alert(#{executable});"
if executable and executable != yes
cs.replace /(\S)\s*\Z/m, "$1\n\nalert #{executable}"
run = if executable is true then 'run' else "run: #{executable}"
name = "example#{counter}"
script = "<script>window.#{name} = #{JSON.stringify cs}</script>"
load = if showLoad then "<div class='minibutton load' onclick='javascript: loadConsole(#{name});'>load</div>" else ''
button = if executable then "<div class='minibutton ok' onclick='javascript: #{js};#{append}'>#{run}</div>" else ''
"<div class='code'>#{cshtml}#{jshtml}#{script}#{load}#{button}<br class='clear' /></div>"
option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'
task 'install', 'install CoffeeScript into /usr/local (or --prefix)', (options) ->
@@ -108,15 +84,21 @@ task 'build:parser', 'rebuild the Jison parser (run build first)', ->
parser = require('./lib/coffee-script/grammar').parser
fs.writeFile 'lib/coffee-script/parser.js', parser.generate()
task 'build:ultraviolet', 'build and install the Ultraviolet syntax highlighter', ->
exec 'plist2syntax ../coffee-script-tmbundle/Syntaxes/CoffeeScript.tmLanguage', (err) ->
throw err if err
exec 'sudo mv coffeescript.yaml /usr/local/lib/ruby/gems/1.8/gems/ultraviolet-0.10.2/syntax/coffeescript.syntax'
task 'build:browser', 'rebuild the merged script for inclusion in the browser', ->
code = ''
for name in ['helpers', 'rewriter', 'lexer', 'parser', 'scope', 'nodes', 'sourcemap', 'coffee-script', 'browser']
code += """
require['./#{name}'] = (function() {
var exports = {}, module = {exports: exports};
require['./#{name}'] = new function() {
var exports = this;
#{fs.readFileSync "lib/coffee-script/#{name}.js"}
return module.exports;
})();
};
"""
code = """
(function(root) {
@@ -141,17 +123,8 @@ task 'build:browser', 'rebuild the merged script for inclusion in the browser',
task 'doc:site', 'watch and continually rebuild the documentation for the website', ->
source = 'documentation/index.html.js'
exec 'bin/coffee -bc -o documentation/js documentation/coffee/*.coffee'
do renderIndex = ->
codeSnippetCounter = 0
rendered = _.template fs.readFileSync(source, 'utf-8'), codeFor: codeFor()
fs.writeFileSync 'index.html', rendered
log "compiled", green, "#{source}"
fs.watchFile source, internal: 200, renderIndex
log "watching..." , green
exec 'rake doc', (err) ->
throw err if err
task 'doc:source', 'rebuild the internal documentation', ->
@@ -187,7 +160,6 @@ task 'bench', 'quick benchmark of compilation time', ->
# Run the CoffeeScript test suite.
runTests = (CoffeeScript) ->
CoffeeScript.register()
startTime = Date.now()
currentFile = null
passedTests = 0
@@ -239,15 +211,20 @@ runTests = (CoffeeScript) ->
log "failed #{failures.length} and #{message}", red
for fail in failures
{error, filename, description, source} = fail
jsFilename = filename.replace(/\.coffee$/,'.js')
match = error.stack?.match(new RegExp(fail.file+":(\\d+):(\\d+)"))
match = error.stack?.match(/on line (\d+):/) unless match
[match, line, col] = match if match
console.log ''
log " #{description}", red if description
log " #{error.stack}", red
log " #{jsFilename}: line #{line ? 'unknown'}, column #{col ? 'unknown'}", red
console.log " #{source}" if source
return
# Run every test in the `test` folder, recording failures.
files = fs.readdirSync 'test'
for file in files when helpers.isCoffee file
for file in files when file.match /\.(lit)?coffee$/i
literate = helpers.isLiterate file
currentFile = filename = path.join 'test', file
code = fs.readFileSync filename

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2014 Jeremy Ashkenas
Copyright (c) 2009-2012 Jeremy Ashkenas
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -19,4 +19,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
OTHER DEALINGS IN THE SOFTWARE.

15
README
View File

@@ -1,11 +1,12 @@
{
} } {
{ { } }
} }{ {
{ }{ } } _____ __ __
{ }{ }{ { } / ____| / _|/ _|
( }{ }{ { ) / ____| / _|/ _|
.- { { } { }} -. | | ___ | |_| |_ ___ ___
( { } { } { } } ) | | / _ \| _| _/ _ \/ _ \
( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
|`-..________ ..-'| | |___| (_) | | | || __/ __/
| | \_____\___/|_| |_| \___|\___|
| ;--.
@@ -21,13 +22,13 @@
CoffeeScript is a little language that compiles into JavaScript.
If you have the Node Package Manager installed:
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
npm install -g coffee-script
(Leave off the -g if you don't wish to install globally.)
Or, if you don't wish to use npm:
sudo bin/cake install
Execute a script:
coffee /path/to/script.coffee
@@ -46,5 +47,5 @@
The source repository:
git://github.com/jashkenas/coffee-script.git
Top 100 contributors are listed here:
All contributors are listed here:
http://github.com/jashkenas/coffee-script/contributors

79
Rakefile Normal file
View File

@@ -0,0 +1,79 @@
require 'rubygems'
require 'erb'
require 'fileutils'
require 'rake/testtask'
require 'json'
desc "Build the documentation page"
task :doc do
source = 'documentation/index.html.erb'
child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" }
at_exit { Process.kill("INT", child) }
Signal.trap("INT") { exit }
loop do
mtime = File.stat(source).mtime
if !@mtime || mtime > @mtime
rendered = ERB.new(File.read(source)).result(binding)
File.open('index.html', 'w+') {|f| f.write(rendered) }
end
@mtime = mtime
sleep 1
end
end
desc "Build coffee-script-source gem"
task :gem do
require 'rubygems'
require 'rubygems/package'
gemspec = Gem::Specification.new do |s|
s.name = 'coffee-script-source'
s.version = JSON.parse(File.read('package.json'))["version"]
s.date = Time.now.strftime("%Y-%m-%d")
s.homepage = "http://jashkenas.github.com/coffee-script/"
s.summary = "The CoffeeScript Compiler"
s.description = <<-EOS
CoffeeScript is a little language that compiles into JavaScript.
Underneath all of those embarrassing braces and semicolons,
JavaScript has always had a gorgeous object model at its heart.
CoffeeScript is an attempt to expose the good parts of JavaScript
in a simple way.
EOS
s.files = [
'lib/coffee_script/coffee-script.js',
'lib/coffee_script/source.rb'
]
s.authors = ['Jeremy Ashkenas']
s.email = 'jashkenas@gmail.com'
s.rubyforge_project = 'coffee-script-source'
s.license = "MIT"
end
file = File.open("coffee-script-source.gem", "w")
Gem::Package.open(file, 'w') do |pkg|
pkg.metadata = gemspec.to_yaml
path = "lib/coffee_script/source.rb"
contents = <<-ERUBY
module CoffeeScript
module Source
def self.bundled_path
File.expand_path("../coffee-script.js", __FILE__)
end
end
end
ERUBY
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
contents = File.read("extras/coffee-script.js")
path = "lib/coffee_script/coffee-script.js"
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
end
end

View File

@@ -1,5 +1,5 @@
###
SkinnyMochaHalfCaffScript Compiler v1.0
CoffeeScript Compiler v1.6.1
Released under the MIT License
###

View File

@@ -1,8 +0,0 @@
$ 'body'
.click (e) ->
$ '.box'
.fadeIn 'fast'
.addClass '.active'
.css 'background', 'white'

View File

@@ -1,6 +0,0 @@
class Person
constructor: (options) ->
{@name, @age, @height} = options
tim = new Person age: 4

View File

@@ -1,7 +0,0 @@
text = "Every literary critic believes he will
outwit history and have the last word"
[first, ..., last] = text.split " "

View File

@@ -2,8 +2,8 @@ numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
start = numbers[0..2]
middle = numbers[3...-2]
middle = numbers[3...6]
end = numbers[-2..]
end = numbers[6..]
copy = numbers[..]

View File

@@ -1,6 +1,8 @@
mobyDick = "Call me Ishmael. Some years ago --
never mind how long precisely -- having little
or no money in my purse, and nothing particular
to interest me on shore, I thought I would sail
about a little and see the watery part of the
world..."
never mind how long precisely -- having little
or no money in my purse, and nothing particular
to interest me on shore, I thought I would sail
about a little and see the watery part of the
world..."

View File

@@ -1,8 +0,0 @@
score = 76
grade = switch
when score < 60 then 'F'
when score < 70 then 'D'
when score < 80 then 'C'
when score < 90 then 'B'
else 'A'
# grade == 'C'

View File

@@ -0,0 +1,64 @@
pre.idle .InheritedClass {
}
pre.idle .TypeName {
color: #21439C;
}
pre.idle .Number {
}
pre.idle .LibraryVariable {
color: #A535AE;
}
pre.idle .Storage {
color: #FF5600;
}
pre.idle .line-numbers {
background-color: #BAD6FD;
color: #000000;
}
pre.idle {
background-color: #FFFFFF;
color: #000000;
}
pre.idle .StringInterpolation {
color: #990000;
}
pre.idle .TagName {
}
pre.idle .LibraryConstant {
color: #A535AE;
}
pre.idle .FunctionArgument {
color: #0076ad;
}
pre.idle .BuiltInConstant {
color: #A535AE;
}
pre.idle .Invalid {
background-color: #990000;
color: #FFFFFF;
}
pre.idle .LibraryClassType {
color: #A535AE;
}
pre.idle .LibraryFunction {
color: #A535AE;
}
pre.idle .TagAttribute {
}
pre.idle .Keyword {
color: #FF5600;
}
pre.idle .UserDefinedConstant {
}
pre.idle .String {
color: #00A33F;
}
pre.idle .FunctionName {
color: #21439C;
}
pre.idle .Variable {
color: #A535AE;
}
pre.idle .Comment {
color: #919191;
}

View File

@@ -1,66 +0,0 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original code:; http://softwaremaniacs.org/media/soft/highlight/styles/tomorrow.css */
/* But forked for CoffeeScript */
.tomorrow-comment, pre .comment, pre .title {
color: #8e908c;
}
.tomorrow-red, pre .variable, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo {
color: #c82829;
}
.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .params, pre .constant {
color: #000000;
}
.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute {
color: #eab700;
}
.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata {
color: #718c00;
}
.tomorrow-aqua, pre .css .hexcolor {
color: #3e999f;
}
.tomorrow-blue, pre .function, pre .function .title, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title {
color: #21439C;
}
.tomorrow-purple, pre .keyword, pre .reserved, pre .javascript .function {
color: #FF5600;
}
pre .subst {
color: #A535AE;
}
pre .literal {
color: #A535AE;
}
pre .property {
color: #A535AE;
}
pre .class .title {
color: #21439C;
}
pre code {
display: block;
background: white;
color: #000000;
}
pre .coffeescript .javascript,
pre .javascript .xml,
pre .tex .formula,
pre .xml .javascript,
pre .xml .vbscript,
pre .xml .css,
pre .xml .cdata {
opacity: 0.5;
}

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -108,18 +108,15 @@
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<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>Override exported methods for non-Node.js engines.
</p>
</div>
<div class="content"><div class='highlight'><pre>
CoffeeScript = require <span class="string">'./coffee-script'</span>
CoffeeScript.require = require
compile = CoffeeScript.compile</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="nv">CoffeeScript.require = </span><span class="nx">require</span></pre></div></div>
</li>
@@ -130,14 +127,16 @@ compile = CoffeeScript.compile</pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Use standard JavaScript <code>eval</code> to eval code.
<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 = {}) -&gt;
options.bare ?= <span class="literal">on</span>
eval compile code, options</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">CoffeeScript.eval = </span><span class="nf">(code, options = {}) -&gt;</span>
<span class="nx">options</span><span class="p">.</span><span class="nx">bare</span> <span class="o">?=</span> <span class="kc">on</span>
<span class="nb">eval</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span></pre></div></div>
</li>
@@ -148,15 +147,16 @@ compile = CoffeeScript.compile</pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Running code does not provide access to this scope.
<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 = {}) -&gt;
options.bare = <span class="literal">on</span>
options.shiftLine = <span class="literal">on</span>
Function(compile code, options)()</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">CoffeeScript.run = </span><span class="nf">(code, options = {}) -&gt;</span>
<span class="nv">options.bare = </span><span class="kc">on</span>
<span class="nb">Function</span><span class="p">(</span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)()</span></pre></div></div>
</li>
@@ -167,12 +167,14 @@ compile = CoffeeScript.compile</pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>If we&#39;re not in a browser environment, we&#39;re finished with the public API.
<p>If we&#39;re not in a browser environment, we&#39;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="k">return</span> <span class="k">unless</span> <span class="nb">window</span><span class="o">?</span></pre></div></div>
</li>
@@ -183,19 +185,28 @@ compile = CoffeeScript.compile</pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Include source maps where possible. If we&#39;ve got a base64 encoder, a
JSON serializer, and tools for escaping unicode characters, we&#39;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>Load a remote script from the current domain via XHR.
</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 = {}) -&gt;
options.sourceMap = <span class="literal">true</span>
options.inline = <span class="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>
<div class="content"><div class="highlight"><pre><span class="nv">CoffeeScript.load = </span><span class="nf">(url, callback, options = {}) -&gt;</span>
<span class="nv">xhr = </span><span class="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">ActiveXObject</span>
<span class="k">new</span> <span class="nb">window</span><span class="p">.</span><span class="nx">ActiveXObject</span><span class="p">(</span><span class="s">&#39;Microsoft.XMLHTTP&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">XMLHttpRequest</span><span class="p">()</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">open</span> <span class="s">&#39;GET&#39;</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">overrideMimeType</span> <span class="s">&#39;text/plain&#39;</span> <span class="k">if</span> <span class="s">&#39;overrideMimeType&#39;</span> <span class="k">of</span> <span class="nx">xhr</span>
<span class="nv">xhr.onreadystatechange = </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">is</span> <span class="mi">4</span>
<span class="k">if</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">status</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">200</span><span class="p">]</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">responseText</span><span class="p">,</span> <span class="nx">options</span>
<span class="k">else</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;Could not load </span><span class="si">#{</span><span class="nx">url</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">callback</span><span class="p">()</span> <span class="k">if</span> <span class="nx">callback</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">send</span> <span class="kc">null</span></pre></div></div>
</li>
@@ -206,27 +217,32 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Load a remote script from the current domain via XHR.
<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>
</div>
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="function"><span class="title">load</span></span> = (url, callback, options = {}) -&gt;
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> = -&gt;
<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>
<div class="content"><div class="highlight"><pre><span class="nv">runScripts = </span><span class="nf">-&gt;</span>
<span class="nv">scripts = </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span> <span class="s">&#39;script&#39;</span>
<span class="nv">coffeetypes = </span><span class="p">[</span><span class="s">&#39;text/coffeescript&#39;</span><span class="p">,</span> <span class="s">&#39;text/literate-coffeescript&#39;</span><span class="p">]</span>
<span class="nv">coffees = </span><span class="p">(</span><span class="nx">s</span> <span class="k">for</span> <span class="nx">s</span> <span class="k">in</span> <span class="nx">scripts</span> <span class="k">when</span> <span class="nx">s</span><span class="p">.</span><span class="nx">type</span> <span class="k">in</span> <span class="nx">coffeetypes</span><span class="p">)</span>
<span class="nv">index = </span><span class="mi">0</span>
<span class="nv">length = </span><span class="nx">coffees</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">do</span> <span class="nv">execute = </span><span class="nf">-&gt;</span>
<span class="nv">script = </span><span class="nx">coffees</span><span class="p">[</span><span class="nx">index</span><span class="o">++</span><span class="p">]</span>
<span class="nv">mediatype = </span><span class="nx">script</span><span class="o">?</span><span class="p">.</span><span class="nx">type</span>
<span class="k">if</span> <span class="nx">mediatype</span> <span class="k">in</span> <span class="nx">coffeetypes</span>
<span class="nv">options = </span><span class="p">{</span><span class="nv">literate: </span><span class="nx">mediatype</span> <span class="o">is</span> <span class="s">&#39;text/literate-coffeescript&#39;</span><span class="p">}</span>
<span class="k">if</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">load</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span><span class="p">,</span> <span class="nx">execute</span><span class="p">,</span> <span class="nx">options</span>
<span class="k">else</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">script</span><span class="p">.</span><span class="nx">innerHTML</span><span class="p">,</span> <span class="nx">options</span>
<span class="nx">execute</span><span class="p">()</span>
<span class="kc">null</span></pre></div></div>
</li>
@@ -237,50 +253,18 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</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.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">runScripts</span></span> = -&gt;
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> = -&gt;
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>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Listen for window load, both in decent browsers and in IE.
<p>Listen for window load, both in 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="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span>
<span class="nx">addEventListener</span> <span class="s">&#39;DOMContentLoaded&#39;</span><span class="p">,</span> <span class="nx">runScripts</span><span class="p">,</span> <span class="kc">no</span>
<span class="k">else</span>
<span class="nx">attachEvent</span> <span class="s">&#39;onload&#39;</span><span class="p">,</span> <span class="nx">runScripts</span>
</pre></div></div>
</li>

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -116,10 +116,22 @@ 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&#39;s Cakefile.
</p>
<p>External dependencies.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">fs = </span><span class="nx">require</span> <span class="s">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s">&#39;path&#39;</span>
<span class="nv">helpers = </span><span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<span class="nv">optparse = </span><span class="nx">require</span> <span class="s">&#39;./optparse&#39;</span>
<span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="nv">existsSync = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">existsSync</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">existsSync</span></pre></div></div>
</li>
@@ -129,18 +141,17 @@ current directory&#39;s Cakefile.
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>External dependencies.
<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><span class="nv">tasks = </span><span class="p">{}</span>
<span class="nv">options = </span><span class="p">{}</span>
<span class="nv">switches = </span><span class="p">[]</span>
<span class="nv">oparse = </span><span class="kc">null</span></pre></div></div>
</li>
@@ -151,15 +162,14 @@ existsSync = fs.existsSync <span class="keyword">or</span> path.existsSync</pr
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Keep track of the list of defined tasks, the accepted options, and so on.
<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><span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">global</span><span class="p">,</span></pre></div></div>
</li>
@@ -170,12 +180,17 @@ oparse = <span class="literal">null</span></pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Mixin the top-level Cake functions for Cakefiles to use directly.
<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="nv">task: </span><span class="nf">(name, description, action) -&gt;</span>
<span class="p">[</span><span class="nx">action</span><span class="p">,</span> <span class="nx">description</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">description</span><span class="p">,</span> <span class="nx">action</span><span class="p">]</span> <span class="k">unless</span> <span class="nx">action</span>
<span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="nx">name</span><span class="p">,</span> <span class="nx">description</span><span class="p">,</span> <span class="nx">action</span><span class="p">}</span></pre></div></div>
</li>
@@ -186,15 +201,17 @@ oparse = <span class="literal">null</span></pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</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>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) -&gt;
[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="nv">option: </span><span class="nf">(letter, flag, description) -&gt;</span>
<span class="nx">switches</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">letter</span><span class="p">,</span> <span class="nx">flag</span><span class="p">,</span> <span class="nx">description</span><span class="p">]</span></pre></div></div>
</li>
@@ -205,15 +222,16 @@ and the function to run as the action itself.
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</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>Invoke another task in the current Cakefile.
</p>
</div>
<div class="content"><div class='highlight'><pre> option: (letter, flag, description) -&gt;
switches.push [letter, flag, description]</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">invoke: </span><span class="nf">(name) -&gt;</span>
<span class="nx">missingTask</span> <span class="nx">name</span> <span class="k">unless</span> <span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span>
<span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">].</span><span class="nx">action</span> <span class="nx">options</span></pre></div></div>
</li>
@@ -224,14 +242,28 @@ as the first argument to the action.
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Invoke another task in the current Cakefile.
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node&#39;s
asynchrony may cause tasks to execute in a different order than you&#39;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) -&gt;
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="nv">exports.run = </span><span class="nf">-&gt;</span>
<span class="nv">global.__originalDirname = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span> <span class="s">&#39;.&#39;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">chdir</span> <span class="nx">cakefileDirectory</span> <span class="nx">__originalDirname</span>
<span class="nv">args = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">..]</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s">&#39;Cakefile&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">(),</span> <span class="nv">filename: </span><span class="s">&#39;Cakefile&#39;</span>
<span class="nv">oparse = </span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">switches</span>
<span class="k">return</span> <span class="nx">printTasks</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span>
<span class="k">try</span>
<span class="nv">options = </span><span class="nx">oparse</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span>
<span class="k">catch</span> <span class="nx">e</span>
<span class="k">return</span> <span class="nx">fatalError</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">e</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">invoke</span> <span class="nx">arg</span> <span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span></pre></div></div>
</li>
@@ -242,26 +274,23 @@ as the first argument to the action.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node&#39;s
asynchrony may cause tasks to execute in a different order than you&#39;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>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> = -&gt;
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="nv">printTasks = </span><span class="nf">-&gt;</span>
<span class="nv">relative = </span><span class="nx">path</span><span class="p">.</span><span class="nx">relative</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span>
<span class="nv">cakefilePath = </span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">relative</span><span class="p">(</span><span class="nx">__originalDirname</span><span class="p">,</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()),</span> <span class="s">&#39;Cakefile&#39;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">cakefilePath</span><span class="si">}</span><span class="s"> defines the following tasks:\n&quot;</span>
<span class="k">for</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">task</span> <span class="k">of</span> <span class="nx">tasks</span>
<span class="nv">spaces = </span><span class="mi">20</span> <span class="o">-</span> <span class="nx">name</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">spaces</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s">&#39;&#39;</span>
<span class="nv">desc = </span><span class="k">if</span> <span class="nx">task</span><span class="p">.</span><span class="nx">description</span> <span class="k">then</span> <span class="s">&quot;</span><span class="err">#</span><span class="s"> </span><span class="si">#{</span><span class="nx">task</span><span class="p">.</span><span class="nx">description</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;cake </span><span class="si">#{</span><span class="nx">name</span><span class="si">}#{</span><span class="nx">spaces</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">desc</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="nx">oparse</span><span class="p">.</span><span class="nx">help</span><span class="p">()</span> <span class="k">if</span> <span class="nx">switches</span><span class="p">.</span><span class="nx">length</span></pre></div></div>
</li>
@@ -272,21 +301,19 @@ original directory name, when running Cake tasks from subdirectories.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Display the list of Cake tasks in a format similar to <code>rake -T</code>
<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> = -&gt;
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 &gt; <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="nv">fatalError = </span><span class="nf">(message) -&gt;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span> <span class="nx">message</span> <span class="o">+</span> <span class="s">&#39;\n&#39;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&#39;To see a list of all tasks/options, run &quot;cake&quot;&#39;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span>
<span class="nv">missingTask = </span><span class="nf">(task) -&gt;</span> <span class="nx">fatalError</span> <span class="s">&quot;No such task: </span><span class="si">#{</span><span class="nx">task</span><span class="si">}</span><span class="s">&quot;</span></pre></div></div>
</li>
@@ -297,38 +324,20 @@ original directory name, when running Cake tasks from subdirectories.
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</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) -&gt;
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) -&gt; 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">&#182;</a>
</div>
<p>When <code>cake</code> is invoked, search in the current and all parent directories
<p>When <code>cake</code> is invoked, search in the current and all parent directories
to find the relevant Cakefile.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">cakefileDirectory</span></span> = (dir) -&gt;
<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="nv">cakefileDirectory = </span><span class="nf">(dir) -&gt;</span>
<span class="k">return</span> <span class="nx">dir</span> <span class="k">if</span> <span class="nx">existsSync</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="s">&#39;Cakefile&#39;</span>
<span class="nv">parent = </span><span class="nx">path</span><span class="p">.</span><span class="nx">normalize</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="s">&#39;..&#39;</span>
<span class="k">return</span> <span class="nx">cakefileDirectory</span> <span class="nx">parent</span> <span class="k">unless</span> <span class="nx">parent</span> <span class="o">is</span> <span class="nx">dir</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;Cakefile not found in </span><span class="si">#{</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span><span class="si">}</span><span class="s">&quot;</span>
</pre></div></div>
</li>

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -109,22 +109,26 @@
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<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
on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
contains the main entry functions for tokenizing, parsing, and compiling
source CoffeeScript into JavaScript.
</p>
<p>If included on a webpage, it will automatically sniff out, compile, and
execute all scripts present in <code>text/coffeescript</code> tags.
</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><span class="nv">fs = </span><span class="nx">require</span> <span class="s">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s">&#39;path&#39;</span>
<span class="p">{</span><span class="nx">Lexer</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./lexer&#39;</span>
<span class="p">{</span><span class="nx">parser</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./parser&#39;</span>
<span class="nv">helpers = </span><span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<span class="nv">vm = </span><span class="nx">require</span> <span class="s">&#39;vm&#39;</span>
<span class="nv">sourcemap = </span><span class="nx">require</span> <span class="s">&#39;./sourcemap&#39;</span></pre></div></div>
</li>
@@ -135,12 +139,21 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>The current CoffeeScript version number.
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.
</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="nv">loadFile = </span><span class="nf">(module, filename) -&gt;</span>
<span class="nv">raw = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span> <span class="nx">filename</span><span class="p">,</span> <span class="s">&#39;utf8&#39;</span>
<span class="nv">stripped = </span><span class="k">if</span> <span class="nx">raw</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">is</span> <span class="mh">0xFEFF</span> <span class="k">then</span> <span class="nx">raw</span><span class="p">.</span><span class="nx">substring</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">raw</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">compile</span><span class="p">(</span><span class="nx">stripped</span><span class="p">,</span> <span class="p">{</span><span class="nx">filename</span><span class="p">,</span> <span class="nv">literate: </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">isLiterate</span> <span class="nx">filename</span><span class="p">}),</span> <span class="nx">filename</span>
<span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="k">for</span> <span class="nx">ext</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;.coffee&#39;</span><span class="p">,</span> <span class="s">&#39;.litcoffee&#39;</span><span class="p">,</span> <span class="s">&#39;.md&#39;</span><span class="p">,</span> <span class="s">&#39;.coffee.md&#39;</span><span class="p">]</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span><span class="p">[</span><span class="nx">ext</span><span class="p">]</span> <span class="o">=</span> <span class="nx">loadFile</span></pre></div></div>
</li>
@@ -151,12 +164,14 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Expose helpers for testing.
<p>The current CoffeeScript version number.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.helpers = helpers</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.VERSION = </span><span class="s">&#39;1.6.1&#39;</span></pre></div></div>
</li>
@@ -167,35 +182,14 @@ SourceMap = require <span class="string">'./sourcemap'</span></pre></div></d
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
<p>Expose helpers for testing.
</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>exports.compile = <span class="function"><span class="title">compile</span></span> = (code, options = {}) -&gt;
{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="nv">exports.helpers = </span><span class="nx">helpers</span></pre></div></div>
</li>
@@ -206,20 +200,39 @@ lookups.
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Update the sourcemap with data from each fragment
<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.
</p>
<p>This returns a javascript string, unless <code>options.sourceMap</code> is passed,
in which case this returns a `{js, v3SourceMap, sourceMap}
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="nv">exports.compile = compile = </span><span class="nf">(code, options = {}) -&gt;</span>
<span class="p">{</span><span class="nx">merge</span><span class="p">}</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">helpers</span>
<span class="k">try</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sourceMap</span>
<span class="nv">coffeeFile = </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">baseFileName</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span>
<span class="nv">jsFile = </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">baseFileName</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="p">,</span> <span class="kc">yes</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.js&quot;</span>
<span class="nv">sourceMap = </span><span class="k">new</span> <span class="nx">sourcemap</span><span class="p">.</span><span class="nx">SourceMap</span><span class="p">()</span>
<span class="nv">fragments = </span><span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)).</span><span class="nx">compileToFragments</span> <span class="nx">options</span>
<span class="nv">currentLine = </span><span class="mi">0</span>
<span class="nx">currentLine</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">header</span>
<span class="nx">currentLine</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sourceMap</span>
<span class="nv">currentColumn = </span><span class="mi">0</span>
<span class="nv">js = </span><span class="s">&quot;&quot;</span>
<span class="k">for</span> <span class="nx">fragment</span> <span class="k">in</span> <span class="nx">fragments</span></pre></div></div>
</li>
@@ -230,24 +243,22 @@ lookups.
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Copy the code from each fragment into the final JavaScript.
<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="k">if</span> <span class="nx">sourceMap</span>
<span class="k">if</span> <span class="nx">fragment</span><span class="p">.</span><span class="nx">locationData</span>
<span class="nx">sourceMap</span><span class="p">.</span><span class="nx">addMapping</span><span class="p">(</span>
<span class="p">[</span><span class="nx">fragment</span><span class="p">.</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_line</span><span class="p">,</span> <span class="nx">fragment</span><span class="p">.</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_column</span><span class="p">],</span>
<span class="p">[</span><span class="nx">currentLine</span><span class="p">,</span> <span class="nx">currentColumn</span><span class="p">],</span>
<span class="p">{</span><span class="nv">noReplace: </span><span class="kc">true</span><span class="p">})</span>
<span class="nv">newLines = </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">count</span> <span class="nx">fragment</span><span class="p">.</span><span class="nx">code</span><span class="p">,</span> <span class="s">&quot;\n&quot;</span>
<span class="nx">currentLine</span> <span class="o">+=</span> <span class="nx">newLines</span>
<span class="nv">currentColumn = </span><span class="nx">fragment</span><span class="p">.</span><span class="nx">code</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="p">(</span><span class="k">if</span> <span class="nx">newLines</span> <span class="k">then</span> <span class="nx">fragment</span><span class="p">.</span><span class="nx">code</span><span class="p">.</span><span class="nx">lastIndexOf</span> <span class="s">&quot;\n&quot;</span> <span class="k">else</span> <span class="mi">0</span><span class="p">)</span></pre></div></div>
</li>
@@ -258,13 +269,31 @@ lookups.
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Tokenize a string of CoffeeScript code, and return the array of tokens.
<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) -&gt;
lexer.tokenize code, options</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nx">js</span> <span class="o">+=</span> <span class="nx">fragment</span><span class="p">.</span><span class="nx">code</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nv">err.message = </span><span class="s">&quot;In </span><span class="si">#{</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">throw</span> <span class="nx">err</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">header</span>
<span class="nv">header = </span><span class="s">&quot;Generated by CoffeeScript </span><span class="si">#{</span><span class="nx">@VERSION</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">js = </span><span class="s">&quot;// </span><span class="si">#{</span><span class="nx">header</span><span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">js</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sourceMap</span>
<span class="nv">answer = </span><span class="p">{</span><span class="nx">js</span><span class="p">}</span>
<span class="k">if</span> <span class="nx">sourceMap</span>
<span class="nv">answer.sourceMap = </span><span class="nx">sourceMap</span>
<span class="nv">answer.v3SourceMap = </span><span class="nx">sourcemap</span><span class="p">.</span><span class="nx">generateV3SourceMap</span> <span class="nx">sourceMap</span><span class="p">,</span> <span class="nx">coffeeFile</span><span class="p">,</span> <span class="nx">jsFile</span>
<span class="nx">answer</span>
<span class="k">else</span>
<span class="nx">js</span></pre></div></div>
</li>
@@ -275,18 +304,15 @@ lookups.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</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>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) -&gt;
<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="nv">exports.tokens = </span><span class="nf">(code, options) -&gt;</span>
<span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span></pre></div></div>
</li>
@@ -297,15 +323,20 @@ or traverse it by using <code>.traverseChildren()</code> with a callback.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</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>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 = {}) -&gt;
mainModule = require.main
options.sourceMap ?= <span class="literal">true</span></pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.nodes = </span><span class="nf">(source, options) -&gt;</span>
<span class="k">if</span> <span class="k">typeof</span> <span class="nx">source</span> <span class="o">is</span> <span class="s">&#39;string&#39;</span>
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">options</span>
<span class="k">else</span>
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">source</span></pre></div></div>
</li>
@@ -316,13 +347,16 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Set the filename.
<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="nv">exports.run = </span><span class="nf">(code, options = {}) -&gt;</span>
<span class="nv">mainModule = </span><span class="nx">require</span><span class="p">.</span><span class="nx">main</span></pre></div></div>
</li>
@@ -333,12 +367,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Clear the module cache.
<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> <span class="nv">mainModule.filename = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span> <span class="k">then</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="k">else</span> <span class="s">&#39;.&#39;</span></pre></div></div>
</li>
@@ -349,12 +386,14 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Assign paths for node_modules loading
<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> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">moduleCache</span> <span class="o">and=</span> <span class="p">{}</span></pre></div></div>
</li>
@@ -365,13 +404,14 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Compile.
<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> <span class="nv">mainModule.paths = </span><span class="nx">require</span><span class="p">(</span><span class="s">&#39;module&#39;</span><span class="p">).</span><span class="nx">_nodeModulePaths</span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span></pre></div></div>
</li>
@@ -382,17 +422,17 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Attach sourceMap object to sourceMaps[options.filename] so that
it is accessible by Error.prepareStackTrace.
<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="k">if</span> <span class="o">not</span> <span class="nx">helpers</span><span class="p">.</span><span class="nx">isCoffee</span><span class="p">(</span><span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="o">or</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="nx">mainModule</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">compile</span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">),</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">else</span>
<span class="nx">mainModule</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span></pre></div></div>
</li>
@@ -403,27 +443,29 @@ it is accessible by Error.prepareStackTrace.
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
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 = {}) -&gt;
<span class="keyword">return</span> <span class="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
sandbox = options.sandbox
<span class="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.__dirname = path.dirname sandbox.__filename</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.eval = </span><span class="nf">(code, options = {}) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nv">code = </span><span class="nx">code</span><span class="p">.</span><span class="nx">trim</span><span class="p">()</span>
<span class="nv">Script = </span><span class="nx">vm</span><span class="p">.</span><span class="nx">Script</span>
<span class="k">if</span> <span class="nx">Script</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sandbox</span><span class="o">?</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sandbox</span> <span class="k">instanceof</span> <span class="nx">Script</span><span class="p">.</span><span class="nx">createContext</span><span class="p">().</span><span class="nx">constructor</span>
<span class="nv">sandbox = </span><span class="nx">options</span><span class="p">.</span><span class="nx">sandbox</span>
<span class="k">else</span>
<span class="nv">sandbox = </span><span class="nx">Script</span><span class="p">.</span><span class="nx">createContext</span><span class="p">()</span>
<span class="nx">sandbox</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span> <span class="k">for</span> <span class="k">own</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sandbox</span>
<span class="nv">sandbox.global = sandbox.root = sandbox.GLOBAL = </span><span class="nx">sandbox</span>
<span class="k">else</span>
<span class="nv">sandbox = </span><span class="nx">global</span>
<span class="nv">sandbox.__filename = </span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span> <span class="o">||</span> <span class="s">&#39;eval&#39;</span>
<span class="nv">sandbox.__dirname = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">__filename</span></pre></div></div>
</li>
@@ -434,17 +476,19 @@ The CoffeeScript REPL uses this to run the input.
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>define module/require only if they chose not to specify their own
<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) -&gt; Module._load path, _module, <span class="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>
<div class="content"><div class="highlight"><pre> <span class="k">unless</span> <span class="nx">sandbox</span> <span class="o">isnt</span> <span class="nx">global</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">module</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">require</span>
<span class="nv">Module = </span><span class="nx">require</span> <span class="s">&#39;module&#39;</span>
<span class="nv">sandbox.module = _module = </span><span class="k">new</span> <span class="nx">Module</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">modulename</span> <span class="o">||</span> <span class="s">&#39;eval&#39;</span><span class="p">)</span>
<span class="nv">sandbox.require = _require = </span><span class="nf">(path) -&gt;</span> <span class="nx">Module</span><span class="p">.</span><span class="nx">_load</span> <span class="nx">path</span><span class="p">,</span> <span class="nx">_module</span><span class="p">,</span> <span class="kc">true</span>
<span class="nv">_module.filename = </span><span class="nx">sandbox</span><span class="p">.</span><span class="nx">__filename</span>
<span class="nx">_require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="o">=</span> <span class="nx">require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="k">for</span> <span class="nx">r</span> <span class="k">in</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span> <span class="nx">require</span> <span class="k">when</span> <span class="nx">r</span> <span class="o">isnt</span> <span class="s">&#39;paths&#39;</span></pre></div></div>
</li>
@@ -455,21 +499,23 @@ The CoffeeScript REPL uses this to run the input.
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>use the same hack node currently uses for their own REPL
<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) -&gt; 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>
js = compile code, o
<span class="keyword">if</span> sandbox <span class="keyword">is</span> global
vm.runInThisContext js
<span class="keyword">else</span>
vm.runInContext js, sandbox</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">_require.paths = _module.paths = </span><span class="nx">Module</span><span class="p">.</span><span class="nx">_nodeModulePaths</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span>
<span class="nv">_require.resolve = </span><span class="nf">(request) -&gt;</span> <span class="nx">Module</span><span class="p">.</span><span class="nx">_resolveFilename</span> <span class="nx">request</span><span class="p">,</span> <span class="nx">_module</span>
<span class="nv">o = </span><span class="p">{}</span>
<span class="nx">o</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span> <span class="k">for</span> <span class="k">own</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">options</span>
<span class="nv">o.bare = </span><span class="kc">on</span> <span class="c1"># ensure return value</span>
<span class="nv">js = </span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">sandbox</span> <span class="o">is</span> <span class="nx">global</span>
<span class="nx">vm</span><span class="p">.</span><span class="nx">runInThisContext</span> <span class="nx">js</span>
<span class="k">else</span>
<span class="nx">vm</span><span class="p">.</span><span class="nx">runInContext</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">sandbox</span></pre></div></div>
</li>
@@ -480,17 +526,14 @@ The CoffeeScript REPL uses this to run the input.
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.
<p>Instantiate a Lexer for our use here.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">loadFile</span></span> = (module, filename) -&gt;
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="nv">lexer = </span><span class="k">new</span> <span class="nx">Lexer</span></pre></div></div>
</li>
@@ -501,370 +544,32 @@ The CoffeeScript REPL uses this to run the input.
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</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="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>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Patch Node&#39;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&#39;t be.
</p>
</div>
<div class="content"><div class='highlight'><pre> Module = require <span class="string">'module'</span>
<span class="function"><span class="title">findExtension</span></span> = (filename) -&gt;
extensions = path.basename(filename).split <span class="string">'.'</span></pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Remove the initial dot from dotfiles.
</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>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</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="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) -&gt;
<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>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>If we&#39;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="keyword">if</span> child_process
{fork} = child_process
child_process.<span class="function"><span class="title">fork</span></span> = (path, args = [], options = {}) -&gt;
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>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Instantiate a Lexer for our use here.
</p>
</div>
<div class="content"><div class='highlight'><pre>lexer = <span class="keyword">new</span> Lexer</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>The real Lexer produces a generic stream of tokens. This object provides a
<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 &quot;Jison lexer&quot;.
</p>
</div>
<div class="content"><div class='highlight'><pre>parser.lexer =
lex: -&gt;
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="nv">parser.lexer =</span>
<span class="nv">lex: </span><span class="nf">-&gt;</span>
<span class="nv">token = </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">@pos</span><span class="o">++</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">token</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">@yytext</span><span class="p">,</span> <span class="nx">@yylloc</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
<span class="vi">@yylineno = </span><span class="nx">@yylloc</span><span class="p">.</span><span class="nx">first_line</span>
<span class="k">else</span>
<span class="nv">tag = </span><span class="s">&#39;&#39;</span>
tag
setInput: (<span class="property">@tokens</span>) -&gt;
<span class="property">@pos</span> = <span class="number">0</span>
upcomingInput: -&gt;
<span class="string">""</span></pre></div></div>
</li>
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Make all the AST nodes visible to the parser.
</p>
<span class="nx">tag</span>
<span class="nv">setInput: </span><span class="nf">(@tokens) -&gt;</span>
<span class="vi">@pos = </span><span class="mi">0</span>
<span class="nv">upcomingInput: </span><span class="nf">-&gt;</span>
<span class="s">&quot;&quot;</span>
</div>
<div class="content"><div class='highlight'><pre>parser.yy = require <span class="string">'./nodes'</span></pre></div></div>
</li>
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Override Jison&#39;s default error handling function.
</p>
<span class="nv">parser.yy = </span><span class="nx">require</span> <span class="s">&#39;./nodes&#39;</span>
</div>
<div class="content"><div class='highlight'><pre>parser.yy.<span class="function"><span class="title">parseError</span></span> = (message, {token}) -&gt;</pre></div></div>
</li>
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>Disregard Jison&#39;s message, it contains redundant line numer information.
</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>
</li>
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</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">&#182;</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>
</div>
<div class="content"><div class='highlight'><pre>
patched = <span class="literal">false</span></pre></div></div>
</li>
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Map of filenames -&gt; sourceMap object.
</p>
</div>
<div class="content"><div class='highlight'><pre>sourceMaps = {}
<span class="function"><span class="title">patchStackTrace</span></span> = -&gt;
<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">&#182;</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) -&gt;
sourceFiles = {}
<span class="function"><span class="title">getSourceMapping</span></span> = (filename, line, column) -&gt;
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">&#182;</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) -&gt;
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">"&lt;anonymous&gt;"</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">&#182;</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>, &lt;js&gt;:<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> '&lt;anonymous&gt;'}</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> '&lt;anonymous&gt;'}</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>
</pre></div></div>
</li>

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -109,14 +109,28 @@
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
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
into various forms: saved into <code>.js</code> files or printed to stdout, piped to
<a href="http://javascriptlint.com/">JavaScript Lint</a> or recompiled every time the source is
saved, printed as a token stream or as the syntax tree, or launch an
interactive REPL.
</p>
<p>External dependencies.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">fs = </span><span class="nx">require</span> <span class="s">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s">&#39;path&#39;</span>
<span class="nv">helpers = </span><span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<span class="nv">optparse = </span><span class="nx">require</span> <span class="s">&#39;./optparse&#39;</span>
<span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="p">{</span><span class="nx">spawn</span><span class="p">,</span> <span class="nx">exec</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;child_process&#39;</span>
<span class="p">{</span><span class="nx">EventEmitter</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;events&#39;</span>
<span class="nv">exists = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">exists</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">exists</span></pre></div></div>
</li>
@@ -126,21 +140,19 @@ interactive REPL.
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>External dependencies.
<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><span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">CoffeeScript</span><span class="p">,</span> <span class="k">new</span> <span class="nx">EventEmitter</span>
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="nv">printLine = </span><span class="nf">(line) -&gt;</span> <span class="nx">process</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="nx">line</span> <span class="o">+</span> <span class="s">&#39;\n&#39;</span>
<span class="nv">printWarn = </span><span class="nf">(line) -&gt;</span> <span class="nx">process</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="nx">write</span> <span class="nx">line</span> <span class="o">+</span> <span class="s">&#39;\n&#39;</span>
<span class="nv">hidden = </span><span class="nf">(file) -&gt;</span> <span class="o">/^</span><span class="err">\</span><span class="p">.</span><span class="o">|~</span><span class="nx">$</span><span class="o">/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">file</span></pre></div></div>
</li>
@@ -151,17 +163,18 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Allow CoffeeScript to emit Node.js events.
<p>The help banner that is printed when <code>coffee</code> is called without arguments.
</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><span class="nv">BANNER = </span><span class="s">&#39;&#39;&#39;</span>
<span class="s"> Usage: coffee [options] path/to/script.coffee -- [args]</span>
<span class="function"><span class="title">printLine</span></span> = (line) -&gt; process.stdout.write line + <span class="string">'\n'</span>
<span class="function"><span class="title">printWarn</span></span> = (line) -&gt; process.stderr.write line + <span class="string">'\n'</span>
<span class="function"><span class="title">hidden</span></span> = (file) -&gt; <span class="regexp">/^\.|~$/</span>.test file</pre></div></div>
<span class="s"> If called without options, `coffee` will run your script.</span>
<span class="s">&#39;&#39;&#39;</span></pre></div></div>
</li>
@@ -172,16 +185,31 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>The help banner that is printed when <code>coffee</code> is called without arguments.
<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><span class="nv">SWITCHES = </span><span class="p">[</span>
<span class="p">[</span><span class="s">&#39;-b&#39;</span><span class="p">,</span> <span class="s">&#39;--bare&#39;</span><span class="p">,</span> <span class="s">&#39;compile without a top-level function wrapper&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-c&#39;</span><span class="p">,</span> <span class="s">&#39;--compile&#39;</span><span class="p">,</span> <span class="s">&#39;compile to JavaScript and save as .js files&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-e&#39;</span><span class="p">,</span> <span class="s">&#39;--eval&#39;</span><span class="p">,</span> <span class="s">&#39;pass a string from the command line as input&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-h&#39;</span><span class="p">,</span> <span class="s">&#39;--help&#39;</span><span class="p">,</span> <span class="s">&#39;display this help message&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-i&#39;</span><span class="p">,</span> <span class="s">&#39;--interactive&#39;</span><span class="p">,</span> <span class="s">&#39;run an interactive CoffeeScript REPL&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-j&#39;</span><span class="p">,</span> <span class="s">&#39;--join [FILE]&#39;</span><span class="p">,</span> <span class="s">&#39;concatenate the source CoffeeScript before compiling&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-l&#39;</span><span class="p">,</span> <span class="s">&#39;--lint&#39;</span><span class="p">,</span> <span class="s">&#39;pipe the compiled JavaScript through JavaScript Lint&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-m&#39;</span><span class="p">,</span> <span class="s">&#39;--map&#39;</span><span class="p">,</span> <span class="s">&#39;generate source map and save as .map files&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-n&#39;</span><span class="p">,</span> <span class="s">&#39;--nodes&#39;</span><span class="p">,</span> <span class="s">&#39;print out the parse tree that the parser produces&#39;</span><span class="p">]</span>
<span class="p">[</span> <span class="s">&#39;--nodejs [ARGS]&#39;</span><span class="p">,</span> <span class="s">&#39;pass options directly to the &quot;node&quot; binary&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-o&#39;</span><span class="p">,</span> <span class="s">&#39;--output [DIR]&#39;</span><span class="p">,</span> <span class="s">&#39;set the output directory for compiled JavaScript&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-p&#39;</span><span class="p">,</span> <span class="s">&#39;--print&#39;</span><span class="p">,</span> <span class="s">&#39;print out the compiled JavaScript&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-s&#39;</span><span class="p">,</span> <span class="s">&#39;--stdio&#39;</span><span class="p">,</span> <span class="s">&#39;listen for and compile scripts over stdio&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-t&#39;</span><span class="p">,</span> <span class="s">&#39;--tokens&#39;</span><span class="p">,</span> <span class="s">&#39;print out the tokens that the lexer/rewriter produce&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-v&#39;</span><span class="p">,</span> <span class="s">&#39;--version&#39;</span><span class="p">,</span> <span class="s">&#39;display the version number&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-w&#39;</span><span class="p">,</span> <span class="s">&#39;--watch&#39;</span><span class="p">,</span> <span class="s">&#39;watch scripts for changes and rerun commands&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div></div>
</li>
@@ -192,29 +220,19 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>The list of all the valid option flags that <code>coffee</code> knows how to handle.
<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><span class="nv">opts = </span><span class="p">{}</span>
<span class="nv">sources = </span><span class="p">[]</span>
<span class="nv">sourceCode = </span><span class="p">[]</span>
<span class="nv">notSources = </span><span class="p">{}</span>
<span class="nv">watchers = </span><span class="p">{}</span>
<span class="nv">optionParser = </span><span class="kc">null</span></pre></div></div>
</li>
@@ -225,17 +243,31 @@ useWinPathSep = path.sep <span class="keyword">is</span> <span class="string">'
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Top-level objects shared by all the functions.
<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="nv">exports.run = </span><span class="nf">-&gt;</span>
<span class="nx">parseOptions</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">forkNode</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">nodejs</span>
<span class="k">return</span> <span class="nx">usage</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">help</span>
<span class="k">return</span> <span class="nx">version</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">version</span>
<span class="k">return</span> <span class="nx">require</span><span class="p">(</span><span class="s">&#39;./repl&#39;</span><span class="p">).</span><span class="nx">start</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">interactive</span>
<span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span> <span class="o">and</span> <span class="o">!</span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span>
<span class="k">return</span> <span class="nx">printWarn</span> <span class="s">&quot;The --watch feature depends on Node v0.6.0+. You are running </span><span class="si">#{</span><span class="nx">process</span><span class="p">.</span><span class="nx">version</span><span class="si">}</span><span class="s">.&quot;</span>
<span class="k">return</span> <span class="nx">compileStdio</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">stdio</span>
<span class="k">return</span> <span class="nx">compileScript</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nb">eval</span>
<span class="k">return</span> <span class="nx">require</span><span class="p">(</span><span class="s">&#39;./repl&#39;</span><span class="p">).</span><span class="nx">start</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">literals = </span><span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">run</span> <span class="k">then</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">1</span> <span class="k">else</span> <span class="p">[]</span>
<span class="nv">process.argv = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="mi">1</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">literals</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;coffee&#39;</span>
<span class="k">for</span> <span class="nx">source</span> <span class="k">in</span> <span class="nx">sources</span>
<span class="nx">compilePath</span> <span class="nx">source</span><span class="p">,</span> <span class="kc">yes</span><span class="p">,</span> <span class="nx">path</span><span class="p">.</span><span class="nx">normalize</span> <span class="nx">source</span></pre></div></div>
</li>
@@ -246,29 +278,41 @@ optionParser = <span class="literal">null</span></pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</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>Compile a path, which could be a script or a directory. If a directory
is passed, recursively compile all &#39;.coffee&#39;, &#39;.litcoffee&#39;, and &#39;.coffee.md&#39;
extension source files in it and all subdirectories.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">run</span></span> = -&gt;
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><span class="nv">compilePath = </span><span class="nf">(source, topLevel, base) -&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, stats) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">if</span> <span class="nx">err</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;File not found: </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">()</span> <span class="o">and</span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">isnt</span> <span class="s">&#39;node_modules&#39;</span>
<span class="nx">watchDir</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, files) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">err</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nv">index = </span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">source</span>
<span class="nv">files = </span><span class="nx">files</span><span class="p">.</span><span class="nx">filter</span> <span class="nf">(file) -&gt;</span> <span class="o">not</span> <span class="nx">hidden</span> <span class="nx">file</span>
<span class="nx">sources</span><span class="p">[</span><span class="nx">index</span><span class="p">..</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">file</span> <span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">files</span><span class="p">)</span>
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">index</span><span class="p">..</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="nx">files</span><span class="p">.</span><span class="nx">map</span> <span class="nf">-&gt;</span> <span class="kc">null</span>
<span class="nx">files</span><span class="p">.</span><span class="nx">forEach</span> <span class="nf">(file) -&gt;</span>
<span class="nx">compilePath</span> <span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">file</span><span class="p">),</span> <span class="kc">no</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">topLevel</span> <span class="o">or</span> <span class="nx">helpers</span><span class="p">.</span><span class="nx">isCoffee</span> <span class="nx">source</span>
<span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, code) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">err</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nx">compileScript</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">notSources</span><span class="p">[</span><span class="nx">source</span><span class="p">]</span> <span class="o">=</span> <span class="kc">yes</span>
<span class="nx">removeSource</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span></pre></div></div>
</li>
@@ -279,39 +323,47 @@ Many flags cause us to divert before compiling anything. Flags passed after
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Compile a path, which could be a script or a directory. If a directory
is passed, recursively compile all &#39;.coffee&#39;, &#39;.litcoffee&#39;, and &#39;.coffee.md&#39;
extension source files in it and all subdirectories.
<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&#39;s path.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compilePath</span></span> = (source, topLevel, base) -&gt;
fs.stat source, (err, stats) -&gt;
<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) -&gt;
<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) -&gt; <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 -&gt; <span class="literal">null</span>
files.forEach (file) -&gt;
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) -&gt;
<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="nv">compileScript = </span><span class="nf">(file, input, base) -&gt;</span>
<span class="nv">o = </span><span class="nx">opts</span>
<span class="nv">options = </span><span class="nx">compileOptions</span> <span class="nx">file</span>
<span class="k">try</span>
<span class="nv">t = task = </span><span class="p">{</span><span class="nx">file</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">options</span><span class="p">}</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;compile&#39;</span><span class="p">,</span> <span class="nx">task</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">tokens</span> <span class="k">then</span> <span class="nx">printTokens</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">tokens</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">nodes</span> <span class="k">then</span> <span class="nx">printLine</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">nodes</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span><span class="p">).</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">run</span> <span class="k">then</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">join</span> <span class="o">and</span> <span class="nx">t</span><span class="p">.</span><span class="nx">file</span> <span class="o">isnt</span> <span class="nx">o</span><span class="p">.</span><span class="nx">join</span>
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">file</span><span class="p">)]</span> <span class="o">=</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span>
<span class="nx">compileJoin</span><span class="p">()</span>
<span class="k">else</span>
<span class="nv">compiled = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span>
<span class="nv">t.output = </span><span class="nx">compiled</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">map</span>
<span class="nv">t.output = </span><span class="nx">compiled</span><span class="p">.</span><span class="nx">js</span>
<span class="nv">t.sourceMap = </span><span class="nx">compiled</span><span class="p">.</span><span class="nx">v3SourceMap</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;success&#39;</span><span class="p">,</span> <span class="nx">task</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">print</span>
<span class="nx">printLine</span> <span class="nx">t</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">trim</span><span class="p">()</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="o">||</span> <span class="nx">o</span><span class="p">.</span><span class="nx">map</span>
<span class="nx">writeJs</span> <span class="nx">base</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">file</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">output</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">sourceMap</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">lint</span>
<span class="nx">lint</span> <span class="nx">t</span><span class="p">.</span><span class="nx">file</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">output</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;failure&#39;</span><span class="p">,</span> <span class="nx">err</span><span class="p">,</span> <span class="nx">task</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">listeners</span><span class="p">(</span><span class="s">&#39;failure&#39;</span><span class="p">).</span><span class="nx">length</span>
<span class="k">return</span> <span class="nx">printLine</span> <span class="nx">err</span><span class="p">.</span><span class="nx">message</span> <span class="o">+</span> <span class="s">&#39;\x07&#39;</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">printWarn</span> <span class="nx">err</span> <span class="k">instanceof</span> <span class="nb">Error</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">stack</span> <span class="o">or</span> <span class="s">&quot;ERROR: </span><span class="si">#{</span><span class="nx">err</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span></pre></div></div>
</li>
@@ -322,48 +374,21 @@ extension source files in it and all subdirectories.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</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&#39;s path.
<p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
and write them back to <strong>stdout</strong>.
</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>) -&gt;
o = opts
options = compileOptions file, base
<span class="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
sourceCode[sources.indexOf(t.file)] = t.input
compileJoin()
<span class="keyword">else</span>
compiled = CoffeeScript.compile t.input, t.options
t.output = compiled
<span class="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
printLine t.output.trim()
<span class="keyword">else</span> <span class="keyword">if</span> o.compile <span class="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>
printWarn message
process.exit <span class="number">1</span></pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">compileStdio = </span><span class="nf">-&gt;</span>
<span class="nv">code = </span><span class="s">&#39;&#39;</span>
<span class="nv">stdin = </span><span class="nx">process</span><span class="p">.</span><span class="nx">openStdin</span><span class="p">()</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nf">(buffer) -&gt;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span> <span class="k">if</span> <span class="nx">buffer</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;end&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">compileScript</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">code</span></pre></div></div>
</li>
@@ -374,19 +399,21 @@ requested options. If evaluating the script directly sets <code>__filename</code
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
and write them back to <strong>stdout</strong>.
<p>If all of the source files are done being read, concatenate and compile
them together.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">compileStdio</span></span> = -&gt;
code = <span class="string">''</span>
stdin = process.openStdin()
stdin.<span class="literal">on</span> <span class="string">'data'</span>, (buffer) -&gt;
code += buffer.toString() <span class="keyword">if</span> buffer
stdin.<span class="literal">on</span> <span class="string">'end'</span>, -&gt;
compileScript <span class="literal">null</span>, code</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">joinTimeout = </span><span class="kc">null</span>
<span class="nv">compileJoin = </span><span class="nf">-&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span>
<span class="k">unless</span> <span class="nx">sourceCode</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nf">(code) -&gt;</span> <span class="nx">code</span> <span class="o">is</span> <span class="kc">null</span><span class="p">)</span>
<span class="nx">clearTimeout</span> <span class="nx">joinTimeout</span>
<span class="nv">joinTimeout = </span><span class="nx">wait</span> <span class="mi">100</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">compileScript</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span><span class="p">,</span> <span class="nx">sourceCode</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">),</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span></pre></div></div>
</li>
@@ -397,19 +424,52 @@ and write them back to <strong>stdout</strong>.
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>If all of the source files are done being read, concatenate and compile
them together.
<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>--lint</code> or <code>--print</code>.
</p>
</div>
<div class="content"><div class='highlight'><pre>joinTimeout = <span class="literal">null</span>
<span class="function"><span class="title">compileJoin</span></span> = -&gt;
<span class="keyword">return</span> <span class="keyword">unless</span> opts.join
<span class="keyword">unless</span> sourceCode.some((code) -&gt; code <span class="keyword">is</span> <span class="literal">null</span>)
clearTimeout joinTimeout
joinTimeout = wait <span class="number">100</span>, -&gt;
compileScript opts.join, sourceCode.join(<span class="string">'\n'</span>), opts.join</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">watch = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">prevStats = </span><span class="kc">null</span>
<span class="nv">compileTimeout = </span><span class="kc">null</span>
<span class="nv">watchErr = </span><span class="nf">(e) -&gt;</span>
<span class="k">if</span> <span class="nx">e</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">is</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">try</span>
<span class="nx">rewatch</span><span class="p">()</span>
<span class="nx">compile</span><span class="p">()</span>
<span class="k">catch</span> <span class="nx">e</span>
<span class="nx">removeSource</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nx">compileJoin</span><span class="p">()</span>
<span class="k">else</span> <span class="k">throw</span> <span class="nx">e</span>
<span class="nv">compile = </span><span class="nf">-&gt;</span>
<span class="nx">clearTimeout</span> <span class="nx">compileTimeout</span>
<span class="nv">compileTimeout = </span><span class="nx">wait</span> <span class="mi">25</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, stats) -&gt;</span>
<span class="k">return</span> <span class="nx">watchErr</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span>
<span class="k">return</span> <span class="nx">rewatch</span><span class="p">()</span> <span class="k">if</span> <span class="nx">prevStats</span> <span class="o">and</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">size</span> <span class="o">is</span> <span class="nx">prevStats</span><span class="p">.</span><span class="nx">size</span> <span class="o">and</span>
<span class="nx">stats</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">is</span> <span class="nx">prevStats</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span>
<span class="nv">prevStats = </span><span class="nx">stats</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, code) -&gt;</span>
<span class="k">return</span> <span class="nx">watchErr</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span>
<span class="nx">compileScript</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span>
<span class="nx">rewatch</span><span class="p">()</span>
<span class="k">try</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">compile</span>
<span class="k">catch</span> <span class="nx">e</span>
<span class="nx">watchErr</span> <span class="nx">e</span>
<span class="nv">rewatch = </span><span class="nf">-&gt;</span>
<span class="nx">watcher</span><span class="o">?</span><span class="p">.</span><span class="nx">close</span><span class="p">()</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">compile</span></pre></div></div>
</li>
@@ -420,50 +480,39 @@ them together.
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</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>Watch a directory of files for new additions.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">watch</span></span> = (source, base) -&gt;
<div class="content"><div class="highlight"><pre><span class="nv">watchDir = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">readdirTimeout = </span><span class="kc">null</span>
<span class="k">try</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">clearTimeout</span> <span class="nx">readdirTimeout</span>
<span class="nv">readdirTimeout = </span><span class="nx">wait</span> <span class="mi">25</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, files) -&gt;</span>
<span class="k">if</span> <span class="nx">err</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">unless</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nx">watcher</span><span class="p">.</span><span class="nx">close</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">unwatchDir</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">files</span> <span class="k">when</span> <span class="o">not</span> <span class="nx">hidden</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">notSources</span><span class="p">[</span><span class="nx">file</span><span class="p">]</span>
<span class="nv">file = </span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">file</span>
<span class="k">continue</span> <span class="k">if</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">some</span> <span class="nf">(s) -&gt;</span> <span class="nx">s</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nx">sources</span><span class="p">.</span><span class="nx">push</span> <span class="nx">file</span>
<span class="nx">sourceCode</span><span class="p">.</span><span class="nx">push</span> <span class="kc">null</span>
<span class="nx">compilePath</span> <span class="nx">file</span><span class="p">,</span> <span class="kc">no</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">catch</span> <span class="nx">e</span>
<span class="k">throw</span> <span class="nx">e</span> <span class="k">unless</span> <span class="nx">e</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
prevStats = <span class="literal">null</span>
compileTimeout = <span class="literal">null</span>
<span class="function"><span class="title">watchErr</span></span> = (e) -&gt;
<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> = -&gt;
clearTimeout compileTimeout
compileTimeout = wait <span class="number">25</span>, -&gt;
fs.stat source, (err, stats) -&gt;
<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()
prevStats = stats
fs.readFile source, (err, code) -&gt;
<span class="keyword">return</span> watchErr err <span class="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="function"><span class="title">rewatch</span></span> = -&gt;
watcher?.close()
watcher = fs.watch source, compile</pre></div></div>
<span class="nv">unwatchDir = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">prevSources = </span><span class="nx">sources</span><span class="p">[..]</span>
<span class="nv">toRemove = </span><span class="p">(</span><span class="nx">file</span> <span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">sources</span> <span class="k">when</span> <span class="nx">file</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span>
<span class="nx">removeSource</span> <span class="nx">file</span><span class="p">,</span> <span class="nx">base</span><span class="p">,</span> <span class="kc">yes</span> <span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">toRemove</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">some</span> <span class="nf">(s, i) -&gt;</span> <span class="nx">prevSources</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">isnt</span> <span class="nx">s</span>
<span class="nx">compileJoin</span><span class="p">()</span></pre></div></div>
</li>
@@ -474,37 +523,25 @@ such as <code>--print</code>.
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Watch a directory of files for new additions.
<p>Remove a file from our source list, and source code cache. Optionally remove
the compiled JS version as well.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">watchDir</span></span> = (source, base) -&gt;
readdirTimeout = <span class="literal">null</span>
<span class="keyword">try</span>
watcher = fs.watch source, -&gt;
clearTimeout readdirTimeout
readdirTimeout = wait <span class="number">25</span>, -&gt;
fs.readdir source, (err, files) -&gt;
<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) -&gt; s.indexOf(file) &gt;= <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>
<span class="function"><span class="title">unwatchDir</span></span> = (source, base) -&gt;
prevSources = sources[..]
toRemove = (file <span class="keyword">for</span> file <span class="keyword">in</span> sources <span class="keyword">when</span> file.indexOf(source) &gt;= <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) -&gt; prevSources[i] <span class="keyword">isnt</span> s
compileJoin()</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">removeSource = </span><span class="nf">(source, base, removeJs) -&gt;</span>
<span class="nv">index = </span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">source</span>
<span class="nx">sources</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">index</span><span class="p">,</span> <span class="mi">1</span>
<span class="nx">sourceCode</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">index</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">removeJs</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span>
<span class="nv">jsPath = </span><span class="nx">outputPath</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span>
<span class="nx">exists</span> <span class="nx">jsPath</span><span class="p">,</span> <span class="nf">(itExists) -&gt;</span>
<span class="k">if</span> <span class="nx">itExists</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">unlink</span> <span class="nx">jsPath</span><span class="p">,</span> <span class="nf">(err) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nx">timeLog</span> <span class="s">&quot;removed </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span></pre></div></div>
</li>
@@ -515,23 +552,19 @@ such as <code>--print</code>.
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Remove a file from our source list, and source code cache. Optionally remove
the compiled JS version as well.
<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">removeSource</span></span> = (source, base, removeJs) -&gt;
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) -&gt;
<span class="keyword">if</span> itExists
fs.unlink jsPath, (err) -&gt;
<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>
<div class="content"><div class="highlight"><pre><span class="nv">outputPath = </span><span class="nf">(source, base, extension=&quot;.js&quot;) -&gt;</span>
<span class="nv">basename = </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">baseFileName</span> <span class="nx">source</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nv">srcDir = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">source</span>
<span class="nv">baseDir = </span><span class="k">if</span> <span class="nx">base</span> <span class="o">is</span> <span class="s">&#39;.&#39;</span> <span class="k">then</span> <span class="nx">srcDir</span> <span class="k">else</span> <span class="nx">srcDir</span><span class="p">.</span><span class="nx">substring</span> <span class="nx">base</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">dir = </span><span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">output</span> <span class="k">then</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">output</span><span class="p">,</span> <span class="nx">baseDir</span> <span class="k">else</span> <span class="nx">srcDir</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="nx">basename</span> <span class="o">+</span> <span class="nx">extension</span></pre></div></div>
</li>
@@ -542,17 +575,38 @@ the compiled JS version as well.
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Get the corresponding output JavaScript path for a source file.
<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>
<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>
</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>) -&gt;
basename = helpers.baseFileName source, <span class="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
path.join dir, basename + extension</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">writeJs = </span><span class="nf">(base, sourcePath, js, generatedSourceMap = null) -&gt;</span>
<span class="nv">jsPath = </span><span class="nx">outputPath</span> <span class="nx">sourcePath</span><span class="p">,</span> <span class="nx">base</span>
<span class="nv">sourceMapPath = </span><span class="nx">outputPath</span> <span class="nx">sourcePath</span><span class="p">,</span> <span class="nx">base</span><span class="p">,</span> <span class="s">&quot;.map&quot;</span>
<span class="nv">jsDir = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">jsPath</span>
<span class="nv">compile = </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span>
<span class="nv">js = </span><span class="s">&#39; &#39;</span> <span class="k">if</span> <span class="nx">js</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">generatedSourceMap</span> <span class="k">then</span> <span class="nv">js = </span><span class="s">&quot;//@ sourceMappingURL=</span><span class="si">#{</span><span class="nx">helpers</span><span class="p">.</span><span class="nx">baseFileName</span> <span class="nx">sourceMapPath</span><span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">js</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">writeFile</span> <span class="nx">jsPath</span><span class="p">,</span> <span class="nx">js</span><span class="p">,</span> <span class="nf">(err) -&gt;</span>
<span class="k">if</span> <span class="nx">err</span>
<span class="nx">printLine</span> <span class="nx">err</span><span class="p">.</span><span class="nx">message</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">timeLog</span> <span class="s">&quot;compiled </span><span class="si">#{</span><span class="nx">sourcePath</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nx">generatedSourceMap</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">writeFile</span> <span class="nx">sourceMapPath</span><span class="p">,</span> <span class="nx">generatedSourceMap</span><span class="p">,</span> <span class="nf">(err) -&gt;</span>
<span class="k">if</span> <span class="nx">err</span>
<span class="nx">printLine</span> <span class="s">&quot;Could not write source map: </span><span class="si">#{</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">exists</span> <span class="nx">jsDir</span><span class="p">,</span> <span class="nf">(itExists) -&gt;</span>
<span class="k">if</span> <span class="nx">itExists</span> <span class="k">then</span> <span class="nx">compile</span><span class="p">()</span> <span class="k">else</span> <span class="nx">exec</span> <span class="s">&quot;mkdir -p </span><span class="si">#{</span><span class="nx">jsDir</span><span class="si">}</span><span class="s">&quot;</span><span class="p">,</span> <span class="nx">compile</span></pre></div></div>
</li>
@@ -563,35 +617,14 @@ the compiled JS version as well.
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</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>Convenience for cleaner setTimeouts.
</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>
</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>) -&gt;
sourceMapPath = outputPath sourcePath, base, <span class="string">".map"</span>
jsDir = path.dirname jsPath
<span class="function"><span class="title">compile</span></span> = -&gt;
<span class="keyword">if</span> opts.compile
js = <span class="string">' '</span> <span class="keyword">if</span> js.length &lt;= <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) -&gt;
<span class="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) -&gt;
<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) -&gt;
<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>
<div class="content"><div class="highlight"><pre><span class="nv">wait = </span><span class="nf">(milliseconds, func) -&gt;</span> <span class="nx">setTimeout</span> <span class="nx">func</span><span class="p">,</span> <span class="nx">milliseconds</span></pre></div></div>
</li>
@@ -602,12 +635,15 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Convenience for cleaner setTimeouts.
<p>When watching scripts, it&#39;s useful to log changes with the timestamp.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">wait</span></span> = (milliseconds, func) -&gt; setTimeout func, milliseconds</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">timeLog = </span><span class="nf">(message) -&gt;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;</span><span class="si">#{</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">).</span><span class="nx">toLocaleTimeString</span><span class="p">()</span><span class="si">}</span><span class="s"> - </span><span class="si">#{</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span></pre></div></div>
</li>
@@ -618,13 +654,22 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>When watching scripts, it&#39;s useful to log changes with the timestamp.
<p>Pipe compiled JS through JSLint (requires a working <code>jsl</code> command), printing
any errors or warnings that arise.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">timeLog</span></span> = (message) -&gt;
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="nv">lint = </span><span class="nf">(file, js) -&gt;</span>
<span class="nv">printIt = </span><span class="nf">(buffer) -&gt;</span> <span class="nx">printLine</span> <span class="nx">file</span> <span class="o">+</span> <span class="s">&#39;:\t&#39;</span> <span class="o">+</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span>
<span class="nv">conf = </span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s">&#39;/../../extras/jsl.conf&#39;</span>
<span class="nv">jsl = </span><span class="nx">spawn</span> <span class="s">&#39;jsl&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;-nologo&#39;</span><span class="p">,</span> <span class="s">&#39;-stdin&#39;</span><span class="p">,</span> <span class="s">&#39;-conf&#39;</span><span class="p">,</span> <span class="nx">conf</span><span class="p">]</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">write</span> <span class="nx">js</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">end</span><span class="p">()</span></pre></div></div>
</li>
@@ -635,17 +680,19 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Pretty-print a stream of tokens, sans location data.
<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) -&gt;
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="nv">printTokens = </span><span class="nf">(tokens) -&gt;</span>
<span class="nv">strings = </span><span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">tokens</span>
<span class="nv">tag = </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">value = </span><span class="nx">token</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toString</span><span class="p">().</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\n/</span><span class="p">,</span> <span class="s">&#39;\\n&#39;</span><span class="p">)</span>
<span class="s">&quot;[</span><span class="si">#{</span><span class="nx">tag</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">value</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="nx">printLine</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span></pre></div></div>
</li>
@@ -656,21 +703,23 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
<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>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">parseOptions</span></span> = -&gt;
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="nv">parseOptions = </span><span class="nf">-&gt;</span>
<span class="nv">optionParser = </span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span>
<span class="nv">o = opts = </span><span class="nx">optionParser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">..]</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="o">or=</span> <span class="o">!!</span><span class="nx">o</span><span class="p">.</span><span class="nx">output</span>
<span class="nv">o.run = </span><span class="o">not</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">lint</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">map</span><span class="p">)</span>
<span class="nv">o.print = </span><span class="o">!!</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nb">eval</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">stdio</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span><span class="p">))</span>
<span class="nv">sources = </span><span class="nx">o</span><span class="p">.</span><span class="nx">arguments</span>
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="kc">null</span> <span class="k">for</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">sources</span>
<span class="k">return</span></pre></div></div>
</li>
@@ -681,36 +730,21 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>The compile-time options to pass to the CoffeeScript compiler.
<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) -&gt;
answer = {
filename
literate: opts.literate <span class="keyword">or</span> helpers.isLiterate(filename)
bare: opts.bare
header: opts.compile
sourceMap: opts.map
}
<span class="keyword">if</span> filename
<span class="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="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>
answer</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">compileOptions = </span><span class="nf">(filename) -&gt;</span>
<span class="p">{</span>
<span class="nx">filename</span>
<span class="nv">literate: </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">isLiterate</span><span class="p">(</span><span class="nx">filename</span><span class="p">)</span>
<span class="nv">bare: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">bare</span>
<span class="nv">header: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span>
<span class="nv">sourceMap: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">map</span>
<span class="p">}</span></pre></div></div>
</li>
@@ -721,20 +755,22 @@ same directory as the <code>.js</code> file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
<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>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">forkNode</span></span> = -&gt;
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="nv">forkNode = </span><span class="nf">-&gt;</span>
<span class="nv">nodeArgs = </span><span class="nx">opts</span><span class="p">.</span><span class="nx">nodejs</span><span class="p">.</span><span class="nx">split</span> <span class="sr">/\s+/</span>
<span class="nv">args = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">..]</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">args</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s">&#39;--nodejs&#39;</span><span class="p">),</span> <span class="mi">2</span>
<span class="nx">spawn</span> <span class="nx">process</span><span class="p">.</span><span class="nx">execPath</span><span class="p">,</span> <span class="nx">nodeArgs</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">args</span><span class="p">),</span>
<span class="nv">cwd: </span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span>
<span class="nv">env: </span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span>
<span class="nv">customFds: </span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span></pre></div></div>
</li>
@@ -745,14 +781,16 @@ the <code>node</code> binary, preserving the other options.
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
shown.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">usage</span></span> = -&gt;
printLine (<span class="keyword">new</span> optparse.OptionParser SWITCHES, BANNER).help()</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">usage = </span><span class="nf">-&gt;</span>
<span class="nx">printLine</span> <span class="p">(</span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span><span class="p">).</span><span class="nx">help</span><span class="p">()</span></pre></div></div>
</li>
@@ -763,13 +801,16 @@ shown.
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Print the <code>--version</code> message and exit.
<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> = -&gt;
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="nv">version = </span><span class="nf">-&gt;</span>
<span class="nx">printLine</span> <span class="s">&quot;CoffeeScript version </span><span class="si">#{</span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">VERSION</span><span class="si">}</span><span class="s">&quot;</span>
</pre></div></div>
</li>

View File

@@ -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;
@@ -107,12 +99,12 @@ pre, tt, code {
blockquote {
border-left: 5px solid #ccc;
margin: 0;
margin-left: 0;
padding: 1px 0 1px 1em;
}
.sections blockquote p {
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 12px; line-height: 16px;
font-size: 14px; line-height: 19px;
color: #999;
margin: 10px 0 0;
white-space: pre-wrap;
@@ -369,141 +361,66 @@ ul.sections > li > div {
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
pre code {
display: block; padding: 0.5em;
color: #000;
background: #f8f8ff
}
pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
color: #408080;
font-style: italic
}
pre .keyword,
pre .assignment,
pre .literal,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .lisp .title,
pre .subst,
pre .reserved {
color: #954121;
/*font-weight: bold*/
}
pre .number,
pre .hexcolor {
color: #40a070
}
pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
color: #219161;
}
pre .title,
pre .id {
color: #19469D;
}
pre .params {
color: #00F;
}
pre .javascript .title,
pre .lisp .title,
pre .subst {
font-weight: normal
}
pre .class .title,
pre .haskell .label,
pre .tex .command {
color: #458;
font-weight: bold
}
pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
color: #000080;
font-weight: normal
}
pre .attribute,
pre .variable,
pre .instancevar,
pre .lisp .body {
color: #008080
}
pre .regexp {
color: #B68
}
pre .class {
color: #458;
font-weight: bold
}
pre .symbol,
pre .ruby .symbol .string,
pre .ruby .symbol .keyword,
pre .ruby .symbol .keymethods,
pre .lisp .keyword,
pre .tex .special,
pre .input_number {
color: #990073
}
pre .builtin,
pre .constructor,
pre .built_in,
pre .lisp .title {
color: #0086b3
}
pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
color: #999;
font-weight: bold
}
pre .deletion {
background: #fdd
}
pre .addition {
background: #dfd
}
pre .diff .change {
background: #0086b3
}
pre .chunk {
color: #aaa
}
pre .tex .formula {
opacity: 0.5;
}
body .hll { background-color: #ffffcc }
body .c { color: #408080; font-style: italic } /* Comment */
body .err { border: 1px solid #FF0000 } /* Error */
body .k { color: #954121 } /* Keyword */
body .o { color: #666666 } /* Operator */
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
body .cp { color: #BC7A00 } /* Comment.Preproc */
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
body .cs { color: #408080; font-style: italic } /* Comment.Special */
body .gd { color: #A00000 } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #FF0000 } /* Generic.Error */
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
body .gi { color: #00A000 } /* Generic.Inserted */
body .go { color: #808080 } /* Generic.Output */
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
body .gt { color: #0040D0 } /* Generic.Traceback */
body .kc { color: #954121 } /* Keyword.Constant */
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
body .kp { color: #954121 } /* Keyword.Pseudo */
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
body .kt { color: #B00040 } /* Keyword.Type */
body .m { color: #666666 } /* Literal.Number */
body .s { color: #219161 } /* Literal.String */
body .na { color: #7D9029 } /* Name.Attribute */
body .nb { color: #954121 } /* Name.Builtin */
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
body .no { color: #880000 } /* Name.Constant */
body .nd { color: #AA22FF } /* Name.Decorator */
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
body .nf { color: #0000FF } /* Name.Function */
body .nl { color: #A0A000 } /* Name.Label */
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
body .nv { color: #19469D } /* Name.Variable */
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #666666 } /* Literal.Number.Float */
body .mh { color: #666666 } /* Literal.Number.Hex */
body .mi { color: #666666 } /* Literal.Number.Integer */
body .mo { color: #666666 } /* Literal.Number.Oct */
body .sb { color: #219161 } /* Literal.String.Backtick */
body .sc { color: #219161 } /* Literal.String.Char */
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
body .s2 { color: #219161 } /* Literal.String.Double */
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
body .sh { color: #219161 } /* Literal.String.Heredoc */
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
body .sx { color: #954121 } /* Literal.String.Other */
body .sr { color: #BB6688 } /* Literal.String.Regex */
body .s1 { color: #219161 } /* Literal.String.Single */
body .ss { color: #19469D } /* Literal.String.Symbol */
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
body .vc { color: #19469D } /* Name.Variable.Class */
body .vg { color: #19469D } /* Name.Variable.Global */
body .vi { color: #19469D } /* Name.Variable.Instance */
body .il { color: #666666 } /* Literal.Number.Integer.Long */

File diff suppressed because it is too large Load Diff

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -111,10 +111,17 @@
<p>This file contains the common helper functions that we&#39;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>
<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="nv">exports.starts = </span><span class="nf">(string, literal, start) -&gt;</span>
<span class="nx">literal</span> <span class="o">is</span> <span class="nx">string</span><span class="p">.</span><span class="nx">substr</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">literal</span><span class="p">.</span><span class="nx">length</span></pre></div></div>
</li>
@@ -124,13 +131,16 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Peek at the beginning of a given string to see if it matches a sequence.
<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) -&gt;
literal <span class="keyword">is</span> string.substr start, literal.length</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.ends = </span><span class="nf">(string, literal, back) -&gt;</span>
<span class="nv">len = </span><span class="nx">literal</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">literal</span> <span class="o">is</span> <span class="nx">string</span><span class="p">.</span><span class="nx">substr</span> <span class="nx">string</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">len</span> <span class="o">-</span> <span class="p">(</span><span class="nx">back</span> <span class="o">or</span> <span class="mi">0</span><span class="p">),</span> <span class="nx">len</span></pre></div></div>
</li>
@@ -141,14 +151,15 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Peek at the end of a given string to see if it matches a sequence.
<p>Trim out all falsy values from an array.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">ends</span></span> = (string, literal, back) -&gt;
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="nv">exports.compact = </span><span class="nf">(array) -&gt;</span>
<span class="nx">item</span> <span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span> <span class="k">when</span> <span class="nx">item</span></pre></div></div>
</li>
@@ -159,12 +170,18 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Repeat a string <code>n</code> times.
<p>Count the number of occurrences of a string in a string.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.repeat = <span class="function"><span class="title">repeat</span></span> = (str, n) -&gt;</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.count = </span><span class="nf">(string, substr) -&gt;</span>
<span class="nv">num = pos = </span><span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="k">unless</span> <span class="nx">substr</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">num</span><span class="o">++</span> <span class="k">while</span> <span class="nv">pos = </span><span class="mi">1</span> <span class="o">+</span> <span class="nx">string</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">substr</span><span class="p">,</span> <span class="nx">pos</span>
<span class="nx">num</span></pre></div></div>
</li>
@@ -175,17 +192,17 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Use clever algorithm to have O(log(n)) string concatenation operations.
<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> res = <span class="string">''</span>
<span class="keyword">while</span> n &gt; <span class="number">0</span>
res += str <span class="keyword">if</span> n &amp; <span class="number">1</span>
n &gt;&gt;&gt;= <span class="number">1</span>
str += str
res</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.merge = </span><span class="nf">(options, overrides) -&gt;</span>
<span class="nx">extend</span> <span class="p">(</span><span class="nx">extend</span> <span class="p">{},</span> <span class="nx">options</span><span class="p">),</span> <span class="nx">overrides</span></pre></div></div>
</li>
@@ -196,13 +213,17 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Trim out all falsy values from an array.
<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">compact</span></span> = (array) -&gt;
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="nv">extend = exports.extend = </span><span class="nf">(object, properties) -&gt;</span>
<span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">properties</span>
<span class="nx">object</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">val</span>
<span class="nx">object</span></pre></div></div>
</li>
@@ -213,16 +234,22 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Count the number of occurrences of a string in a string.
<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>exports.<span class="function"><span class="title">count</span></span> = (string, substr) -&gt;
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="nv">exports.flatten = flatten = </span><span class="nf">(array) -&gt;</span>
<span class="nv">flattened = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">element</span> <span class="k">in</span> <span class="nx">array</span>
<span class="k">if</span> <span class="nx">element</span> <span class="k">instanceof</span> <span class="nb">Array</span>
<span class="nv">flattened = </span><span class="nx">flattened</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">flatten</span> <span class="nx">element</span>
<span class="k">else</span>
<span class="nx">flattened</span><span class="p">.</span><span class="nx">push</span> <span class="nx">element</span>
<span class="nx">flattened</span></pre></div></div>
</li>
@@ -233,15 +260,18 @@ arrays, count characters, that sort of thing.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</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>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.<span class="function"><span class="title">merge</span></span> = (options, overrides) -&gt;
extend (extend {}, options), overrides</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.del = </span><span class="nf">(obj, key) -&gt;</span>
<span class="nv">val = </span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="nx">val</span></pre></div></div>
</li>
@@ -252,15 +282,14 @@ options hash to propagate down the tree without polluting other branches.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Extend a source object with the properties of another object (shallow copy).
<p>Gets the last item of an array(-like) object.
</p>
</div>
<div class="content"><div class='highlight'><pre>extend = exports.<span class="function"><span class="title">extend</span></span> = (object, properties) -&gt;
<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="nv">exports.last = </span><span class="nf">(array, back) -&gt;</span> <span class="nx">array</span><span class="p">[</span><span class="nx">array</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="p">(</span><span class="nx">back</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span></pre></div></div>
</li>
@@ -271,20 +300,16 @@ options hash to propagate down the tree without polluting other branches.
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Return a flattened version of an array.
Handy for getting a list of <code>children</code> from the nodes.
<p>Typical Array::some
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.flatten = <span class="function"><span class="title">flatten</span></span> = (array) -&gt;
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="nv">exports.some = </span><span class="nb">Array</span><span class="o">::</span><span class="nx">some</span> <span class="o">?</span> <span class="nf">(fn) -&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">for</span> <span class="nx">e</span> <span class="k">in</span> <span class="k">this</span> <span class="k">when</span> <span class="nx">fn</span> <span class="nx">e</span>
<span class="kc">false</span></pre></div></div>
</li>
@@ -295,16 +320,22 @@ Handy for getting a list of <code>children</code> from the nodes.
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</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>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">del</span></span> = (obj, key) -&gt;
val = obj[key]
<span class="keyword">delete</span> obj[key]
val</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">buildLocationData = </span><span class="nf">(first, last) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">last</span>
<span class="nx">first</span>
<span class="k">else</span>
<span class="nv">first_line: </span><span class="nx">first</span><span class="p">.</span><span class="nx">first_line</span>
<span class="nv">first_column: </span><span class="nx">first</span><span class="p">.</span><span class="nx">first_column</span>
<span class="nv">last_line: </span><span class="nx">last</span><span class="p">.</span><span class="nx">last_line</span>
<span class="nv">last_column: </span><span class="nx">last</span><span class="p">.</span><span class="nx">last_column</span></pre></div></div>
</li>
@@ -315,12 +346,20 @@ looking for a particular method in an options hash.
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Gets the last item of an array(-like) object.
<p>This returns a function which takes an object as a parameter, and if that object is an AST node,
updates that object&#39;s locationData. The object is returned either way.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.last = <span class="function"><span class="title">last</span></span> = (array, back) -&gt; 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="nv">exports.addLocationDataFn = </span><span class="nf">(first, last) -&gt;</span>
<span class="nf">(obj) -&gt;</span>
<span class="k">if</span> <span class="p">((</span><span class="k">typeof</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="o">!!</span><span class="nx">obj</span><span class="p">[</span><span class="s">&#39;updateLocationDataIfMissing&#39;</span><span class="p">])</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">updateLocationDataIfMissing</span> <span class="nx">buildLocationData</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">obj</span></pre></div></div>
</li>
@@ -331,14 +370,23 @@ looking for a particular method in an options hash.
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Typical Array::some
<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.some = Array::some ? (fn) -&gt;
<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="nv">exports.locationDataToString = </span><span class="nf">(obj) -&gt;</span>
<span class="k">if</span> <span class="p">(</span><span class="s">&quot;2&quot;</span> <span class="k">of</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="s">&quot;first_line&quot;</span> <span class="k">of</span> <span class="nx">obj</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="k">then</span> <span class="nv">locationData = </span><span class="nx">obj</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">else</span> <span class="k">if</span> <span class="s">&quot;first_line&quot;</span> <span class="k">of</span> <span class="nx">obj</span> <span class="k">then</span> <span class="nv">locationData = </span><span class="nx">obj</span>
<span class="k">if</span> <span class="nx">locationData</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_line</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">:</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_column</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">-&quot;</span> <span class="o">+</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">last_line</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">:</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">last_column</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="s">&quot;No location data&quot;</span></pre></div></div>
</li>
@@ -349,23 +397,21 @@ looking for a particular method in an options hash.
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</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 &quot;normally&quot;.
<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">invertLiterate</span></span> = (code) -&gt;
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="nv">exports.baseFileName = </span><span class="nf">(file, stripExt = no) -&gt;</span>
<span class="nv">parts = </span><span class="nx">file</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
<span class="nv">file = </span><span class="nx">parts</span><span class="p">[</span><span class="nx">parts</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">return</span> <span class="nx">file</span> <span class="k">unless</span> <span class="nx">stripExt</span>
<span class="nv">parts = </span><span class="nx">file</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s">&#39;.&#39;</span><span class="p">)</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">parts</span><span class="p">[</span><span class="nx">parts</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="s">&#39;coffee&#39;</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;.&#39;</span><span class="p">)</span></pre></div></div>
</li>
@@ -376,20 +422,14 @@ can be compiled &quot;normally&quot;.
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</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>Determine if a filename represents a CoffeeScript file.
</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildLocationData</span></span> = (first, last) -&gt;
<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="nv">exports.isCoffee = </span><span class="nf">(file) -&gt;</span> <span class="o">/</span><span class="err">\</span><span class="p">.((</span><span class="nx">lit</span><span class="p">)</span><span class="o">?</span><span class="nx">coffee</span><span class="o">|</span><span class="nx">coffee</span><span class="err">\</span><span class="p">.</span><span class="nx">md</span><span class="p">)</span><span class="nx">$</span><span class="o">/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">file</span></pre></div></div>
</li>
@@ -400,192 +440,15 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</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&#39;s locationData.
The object is returned either way.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">addLocationDataFn</span></span> = (first, last) -&gt;
(obj) -&gt;
<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)
<span class="keyword">return</span> obj</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Convert jison location data to a string.
<code>obj</code> can be a token, or a locationData.
<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">locationDataToString</span></span> = (obj) -&gt;
<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
<div class="content"><div class="highlight"><pre><span class="nv">exports.isLiterate = </span><span class="nf">(file) -&gt;</span> <span class="o">/</span><span class="err">\</span><span class="p">.(</span><span class="nx">litcoffee</span><span class="o">|</span><span class="nx">coffee</span><span class="err">\</span><span class="p">.</span><span class="nx">md</span><span class="p">)</span><span class="nx">$</span><span class="o">/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">file</span>
<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>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<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">baseFileName</span></span> = (file, stripExt = <span class="literal">no</span>, useWinPathSep = <span class="literal">no</span>) -&gt;
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 &gt; <span class="number">1</span>
parts.join(<span class="string">'.'</span>)</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<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">isCoffee</span></span> = (file) -&gt; <span class="regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<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">isLiterate</span></span> = (file) -&gt; <span class="regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Throws a SyntaxError with a source file location data attached to it in a
property called <code>location</code>.
</p>
</div>
<div class="content"><div class='highlight'><pre>exports.<span class="function"><span class="title">throwSyntaxError</span></span> = (message, location) -&gt;
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>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Creates a nice error message like, following the &quot;standard&quot; format
</p>
<p><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">prettyErrorMessage</span></span> = (error, fileName, code, useColors) -&gt;
<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>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Show only the first line on multi-line errors.
</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)
<span class="keyword">if</span> useColors
<span class="function"><span class="title">colorize</span></span> = (str) -&gt; <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
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>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Uncomment to add stacktrace.
message += &quot;\n#{error.stack}&quot;
</p>
</div>
<div class="content"><div class='highlight'><pre>
message</pre></div></div>
</pre></div></div>
</li>

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -113,7 +113,9 @@
</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="nx">exports</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">val</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</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

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -108,10 +108,20 @@
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</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>
<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>{repeat} = require <span class="string">'./helpers'</span></pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.OptionParser = </span><span class="k">class</span> <span class="nx">OptionParser</span></pre></div></div>
</li>
@@ -122,19 +132,19 @@
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
Use it like so:
<p>Initialize with a list of valid options, in the form:
</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.
<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>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="nv">constructor: </span><span class="nf">(rules, @banner) -&gt;</span>
<span class="vi">@rules = </span><span class="nx">buildRules</span> <span class="nx">rules</span></pre></div></div>
</li>
@@ -145,17 +155,32 @@ option) list, and all subsequent arguments are left unparsed.
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Initialize with a list of valid options, in the form:
<p>Parse the list of arguments, populating an <code>options</code> object with all of the
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&#39;re responsible for interpreting the options object.
</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>) -&gt;
<span class="property">@rules</span> = buildRules rules</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">parse: </span><span class="nf">(args) -&gt;</span>
<span class="nv">options = arguments: </span><span class="p">[]</span>
<span class="nv">skippingArgument = </span><span class="kc">no</span>
<span class="nv">originalArgs = </span><span class="nx">args</span>
<span class="nv">args = </span><span class="nx">normalizeArguments</span> <span class="nx">args</span>
<span class="k">for</span> <span class="nx">arg</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">args</span>
<span class="k">if</span> <span class="nx">skippingArgument</span>
<span class="nv">skippingArgument = </span><span class="kc">no</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="nx">arg</span> <span class="o">is</span> <span class="s">&#39;--&#39;</span>
<span class="nv">pos = </span><span class="nx">originalArgs</span><span class="p">.</span><span class="nx">indexOf</span> <span class="s">&#39;--&#39;</span>
<span class="nv">options.arguments = </span><span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">originalArgs</span><span class="p">[(</span><span class="nx">pos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)..]</span>
<span class="k">break</span>
<span class="nv">isOption = </span><span class="o">!!</span><span class="p">(</span><span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LONG_FLAG</span><span class="p">)</span> <span class="o">or</span> <span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SHORT_FLAG</span><span class="p">))</span></pre></div></div>
</li>
@@ -166,30 +191,30 @@ option) list, and all subsequent arguments are left unparsed.
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Parse the list of arguments, populating an <code>options</code> object with all of the
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&#39;re responsible for interpreting the options object.
<p>the CS option parser is a little odd; options after the first
non-option argument are treated as non-option arguments themselves
</p>
</div>
<div class="content"><div class='highlight'><pre> parse: (args) -&gt;
options = arguments: []
skippingArgument = <span class="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>
<div class="content"><div class="highlight"><pre> <span class="nv">seenNonOptionArg = </span><span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">unless</span> <span class="nx">seenNonOptionArg</span>
<span class="nv">matchedRule = </span><span class="kc">no</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">is</span> <span class="nx">arg</span> <span class="o">or</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span> <span class="o">is</span> <span class="nx">arg</span>
<span class="nv">value = </span><span class="kc">true</span>
<span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">hasArgument</span>
<span class="nv">skippingArgument = </span><span class="kc">yes</span>
<span class="nv">value = </span><span class="nx">args</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">rule</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">isList</span> <span class="k">then</span> <span class="p">(</span><span class="nx">options</span><span class="p">[</span><span class="nx">rule</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">or</span> <span class="p">[]).</span><span class="nx">concat</span> <span class="nx">value</span> <span class="k">else</span> <span class="nx">value</span>
<span class="nv">matchedRule = </span><span class="kc">yes</span>
<span class="k">break</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;unrecognized option: </span><span class="si">#{</span><span class="nx">arg</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">isOption</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">matchedRule</span>
<span class="k">if</span> <span class="nx">seenNonOptionArg</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">isOption</span>
<span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">arg</span>
<span class="nx">options</span></pre></div></div>
</li>
@@ -200,28 +225,23 @@ you&#39;re responsible for interpreting the options object.
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</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>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.
</p>
</div>
<div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length &gt; <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
options.arguments.push arg
options</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">help: </span><span class="nf">-&gt;</span>
<span class="nv">lines = </span><span class="p">[]</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">unshift</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@banner</span><span class="si">}</span><span class="s">\n&quot;</span> <span class="k">if</span> <span class="nx">@banner</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="nv">spaces = </span><span class="mi">15</span> <span class="o">-</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">spaces</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s">&#39;&#39;</span>
<span class="nv">letPart = </span><span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="k">then</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">+</span> <span class="s">&#39;, &#39;</span> <span class="k">else</span> <span class="s">&#39; &#39;</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">push</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">letPart</span> <span class="o">+</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span> <span class="o">+</span> <span class="nx">spaces</span> <span class="o">+</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">description</span>
<span class="s">&quot;\n</span><span class="si">#{</span> <span class="nx">lines</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">)</span> <span class="si">}</span><span class="s">\n&quot;</span></pre></div></div>
</li>
@@ -229,38 +249,35 @@ non-option argument are treated as non-option arguments themselves
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<div class="pilwrap for-h2">
<a class="pilcrow" href="#section-6">&#182;</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>
<h2>Helpers</h2>
</div>
<div class="content"><div class='highlight'><pre> help: -&gt;
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 &gt; <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>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap for-h2">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<h2>Helpers</h2>
<p>Regex matchers for option flags.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">LONG_FLAG = </span><span class="sr">/^(--\w[\w\-]*)/</span>
<span class="nv">SHORT_FLAG = </span><span class="sr">/^(-\w)$/</span>
<span class="nv">MULTI_FLAG = </span><span class="sr">/^-(\w{2,})/</span>
<span class="nv">OPTIONAL = </span><span class="sr">/\[(\w+(\*?))\]/</span></pre></div></div>
</li>
@@ -271,8 +288,18 @@ of the valid options, for <code>--help</code> and such.
<a class="pilcrow" href="#section-8">&#182;</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>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">buildRules = </span><span class="nf">(rules) -&gt;</span>
<span class="k">for</span> <span class="nx">tuple</span> <span class="k">in</span> <span class="nx">rules</span>
<span class="nx">tuple</span><span class="p">.</span><span class="nx">unshift</span> <span class="kc">null</span> <span class="k">if</span> <span class="nx">tuple</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">3</span>
<span class="nx">buildRule</span> <span class="nx">tuple</span><span class="p">...</span></pre></div></div>
</li>
@@ -282,15 +309,25 @@ of the valid options, for <code>--help</code> and such.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Regex matchers for option flags.
<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>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="nv">buildRule = </span><span class="nf">(shortFlag, longFlag, description, options = {}) -&gt;</span>
<span class="nv">match = </span><span class="nx">longFlag</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">OPTIONAL</span><span class="p">)</span>
<span class="nv">longFlag = </span><span class="nx">longFlag</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LONG_FLAG</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">{</span>
<span class="nv">name: </span> <span class="nx">longFlag</span><span class="p">.</span><span class="nx">substr</span> <span class="mi">2</span>
<span class="nv">shortFlag: </span> <span class="nx">shortFlag</span>
<span class="nv">longFlag: </span> <span class="nx">longFlag</span>
<span class="nv">description: </span> <span class="nx">description</span>
<span class="nv">hasArgument: </span> <span class="o">!!</span><span class="p">(</span><span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="nv">isList: </span> <span class="o">!!</span><span class="p">(</span><span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="p">}</span></pre></div></div>
</li>
@@ -301,68 +338,24 @@ OPTIONAL = <span class="regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</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>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildRules</span></span> = (rules) -&gt;
<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 &lt; <span class="number">3</span>
buildRule tuple...</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</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 = {}) -&gt;
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">&#182;</a>
</div>
<p>Normalize arguments by expanding merged flags into multiple flags. This allows
<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>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">normalizeArguments</span></span> = (args) -&gt;
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>
result.push arg
result</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">normalizeArguments = </span><span class="nf">(args) -&gt;</span>
<span class="nv">args = </span><span class="nx">args</span><span class="p">[..]</span>
<span class="nv">result = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">args</span>
<span class="k">if</span> <span class="nv">match = </span><span class="nx">arg</span><span class="p">.</span><span class="nx">match</span> <span class="nx">MULTI_FLAG</span>
<span class="nx">result</span><span class="p">.</span><span class="nx">push</span> <span class="s">&#39;-&#39;</span> <span class="o">+</span> <span class="nx">l</span> <span class="k">for</span> <span class="nx">l</span> <span class="k">in</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">split</span> <span class="s">&#39;&#39;</span>
<span class="k">else</span>
<span class="nx">result</span><span class="p">.</span><span class="nx">push</span> <span class="nx">arg</span>
<span class="nx">result</span>
</pre></div></div>
</li>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -111,18 +111,14 @@
</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><span class="nv">vm = </span><span class="nx">require</span> <span class="s">&#39;vm&#39;</span>
<span class="nv">nodeREPL = </span><span class="nx">require</span> <span class="s">&#39;repl&#39;</span>
<span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="p">{</span><span class="nx">merge</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
replDefaults =
prompt: <span class="string">'coffee&gt; '</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) -&gt;</pre></div></div>
<span class="nv">replDefaults =</span>
<span class="nv">prompt: </span><span class="s">&#39;coffee&gt; &#39;</span><span class="p">,</span>
<span class="nb">eval</span><span class="o">:</span> <span class="nf">(input, context, filename, cb) -&gt;</span></pre></div></div>
</li>
@@ -133,12 +129,14 @@ replDefaults =
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>XXX: multiline hack.
<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> <span class="nv">input = </span><span class="nx">input</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\uFF00/g</span><span class="p">,</span> <span class="s">&#39;\n&#39;</span></pre></div></div>
</li>
@@ -149,13 +147,14 @@ replDefaults =
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Node&#39;s REPL sends the input ending with a newline and then wrapped in
parens. Unwrap all that.
<p>strip single-line comments
</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> <span class="nv">input = </span><span class="nx">input</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/</span><span class="p">,</span> <span class="s">&#39;$1$2$3&#39;</span></pre></div></div>
</li>
@@ -166,14 +165,14 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Require AST nodes to do some AST manipulation.
<p>empty command
</p>
</div>
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal} = require <span class="string">'./nodes'</span>
<span class="keyword">try</span></pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="k">return</span> <span class="nx">cb</span> <span class="kc">null</span> <span class="k">if</span> <span class="sr">/^(\s*|\(\s*\))$/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">input</span></pre></div></div>
</li>
@@ -184,12 +183,27 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Generate the AST of the clean input.
<p>TODO: fix #1829: pass in-scope vars and avoid accidentally shadowing them by omitting those declarations
</p>
</div>
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes input</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="k">try</span>
<span class="nv">js = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="s">&quot;_=(</span><span class="si">#{</span><span class="nx">input</span><span class="si">}</span><span class="s">\n)&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nx">filename</span><span class="p">,</span> <span class="nv">bare: </span><span class="kc">yes</span><span class="p">}</span>
<span class="nx">cb</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">vm</span><span class="p">.</span><span class="nx">runInContext</span><span class="p">(</span><span class="nx">js</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">filename</span><span class="p">)</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">cb</span> <span class="nx">err</span>
<span class="nv">addMultilineHandler = </span><span class="nf">(repl) -&gt;</span>
<span class="p">{</span><span class="nx">rli</span><span class="p">,</span> <span class="nx">inputStream</span><span class="p">,</span> <span class="nx">outputStream</span><span class="p">}</span> <span class="o">=</span> <span class="nx">repl</span>
<span class="nv">multiline =</span>
<span class="nv">enabled: </span><span class="kc">off</span>
<span class="nv">initialPrompt: </span><span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^[^&gt; ]*/</span><span class="p">,</span> <span class="nf">(x) -&gt;</span> <span class="nx">x</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/./g</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">)</span>
<span class="nv">prompt: </span><span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^[^&gt; ]*&gt;?/</span><span class="p">,</span> <span class="nf">(x) -&gt;</span> <span class="nx">x</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/./g</span><span class="p">,</span> <span class="s">&#39;.&#39;</span><span class="p">)</span>
<span class="nv">buffer: </span><span class="s">&#39;&#39;</span></pre></div></div>
</li>
@@ -200,27 +214,23 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Add assignment to <code>_</code> variable to force the input to be an expression.
<p>Proxy node&#39;s line listener
</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>
]
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) -&gt;
{rli, inputStream, outputStream} = repl
multiline =
enabled: <span class="literal">off</span>
initialPrompt: repl.prompt.replace <span class="regexp">/^[^&gt; ]*/, (x) -&gt; x.replace /./g</span>, <span class="string">'-'</span>
prompt: repl.prompt.replace <span class="regexp">/^[^&gt; ]*&gt;?/, (x) -&gt; x.replace /./g</span>, <span class="string">'.'</span>
buffer: <span class="string">''</span></pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">nodeLineListener = </span><span class="nx">rli</span><span class="p">.</span><span class="nx">listeners</span><span class="p">(</span><span class="s">&#39;line&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">removeListener</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nx">nodeLineListener</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nf">(cmd) -&gt;</span>
<span class="k">if</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">cmd</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">prompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">else</span>
<span class="nx">nodeLineListener</span> <span class="nx">cmd</span>
<span class="k">return</span></pre></div></div>
</li>
@@ -231,21 +241,16 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Proxy node&#39;s line listener
<p>Handle Ctrl-v
</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) -&gt;
<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> <span class="nx">inputStream</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;keypress&#39;</span><span class="p">,</span> <span class="nf">(char, key) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">key</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">ctrl</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">meta</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">shift</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">is</span> <span class="s">&#39;v&#39;</span>
<span class="k">if</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span></pre></div></div>
</li>
@@ -256,14 +261,18 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Handle Ctrl-v
<p>allow arbitrarily switching between modes any time before multiple lines are entered
</p>
</div>
<div class="content"><div class='highlight'><pre> inputStream.<span class="literal">on</span> <span class="string">'keypress'</span>, (char, key) -&gt;
<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> <span class="k">unless</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">match</span> <span class="sr">/\n/</span>
<span class="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">return</span></pre></div></div>
</li>
@@ -274,16 +283,14 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>allow arbitrarily switching between modes any time before multiple lines are entered
<p>no-op unless the current line is empty
</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> <span class="k">return</span> <span class="k">if</span> <span class="nx">rli</span><span class="p">.</span><span class="nx">line</span><span class="o">?</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">rli</span><span class="p">.</span><span class="nx">line</span><span class="p">.</span><span class="nx">match</span> <span class="sr">/^\s*$/</span></pre></div></div>
</li>
@@ -294,12 +301,18 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>no-op unless the current line is empty
<p>eval, print, loop
</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="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nv">rli.line = </span><span class="s">&#39;&#39;</span>
<span class="nv">rli.cursor = </span><span class="mi">0</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">cursorTo</span> <span class="mi">0</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">clearLine</span> <span class="mi">1</span></pre></div></div>
</li>
@@ -310,201 +323,30 @@ parens. Unwrap all that.
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>eval, print, loop
</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>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>XXX: multiline hack
<p>XXX: multiline hack
</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>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Store and load command history from a file
</p>
<div class="content"><div class="highlight"><pre> <span class="nv">multiline.buffer = </span><span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\n/g</span><span class="p">,</span> <span class="s">&#39;\uFF00&#39;</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span>
<span class="nv">multiline.buffer = </span><span class="s">&#39;&#39;</span>
<span class="k">else</span>
<span class="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">initialPrompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">return</span>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">addHistory</span></span> = (repl, filename, maxSize) -&gt;
lastLine = <span class="literal">null</span>
<span class="keyword">try</span></pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Get file info and at most maxSize of command history
</p>
<span class="nv">module.exports =</span>
<span class="nv">start: </span><span class="nf">(opts = {}) -&gt;</span>
<span class="nv">opts = </span><span class="nx">merge</span> <span class="nx">replDefaults</span><span class="p">,</span> <span class="nx">opts</span>
<span class="nv">repl = </span><span class="nx">nodeREPL</span><span class="p">.</span><span class="nx">start</span> <span class="nx">opts</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;exit&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">outputStream</span><span class="p">.</span><span class="nx">write</span> <span class="s">&#39;\n&#39;</span>
<span class="nx">addMultilineHandler</span> <span class="nx">repl</span>
<span class="nx">repl</span>
</div>
<div class="content"><div class='highlight'><pre> stat = fs.statSync filename
size = Math.min maxSize, stat.size</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Read last <code>size</code> bytes from the file
</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>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Set the history on the interpreter
</p>
</div>
<div class="content"><div class='highlight'><pre> repl.rli.history = buffer.toString().split(<span class="string">'\n'</span>).reverse()</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<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.pop() <span class="keyword">if</span> stat.size &gt; maxSize</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Shift off the final blank newline
</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) -&gt;
<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>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Save the latest command in the file
</p>
</div>
<div class="content"><div class='highlight'><pre> fs.write fd, <span class="string">"<span class="subst">#{code}</span>\n"</span>
lastLine = code
repl.rli.<span class="literal">on</span> <span class="string">'exit'</span>, -&gt; fs.close fd</pre></div></div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Add a command to show the history stack
</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: -&gt;
repl.outputStream.write <span class="string">"<span class="subst">#{repl.rli.history[..].reverse().join '\n'}</span>\n"</span>
repl.displayPrompt()
module.exports =
start: (opts = {}) -&gt;
[major, minor, build] = process.versions.node.split(<span class="string">'.'</span>).map (n) -&gt; parseInt(n)
<span class="keyword">if</span> major <span class="keyword">is</span> <span class="number">0</span> <span class="keyword">and</span> minor &lt; <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>
opts = merge replDefaults, opts
repl = nodeREPL.start opts
repl.<span class="literal">on</span> <span class="string">'exit'</span>, -&gt; repl.outputStream.write <span class="string">'\n'</span>
addMultilineHandler repl
addHistory repl, opts.historyFile, opts.historyMaxInputSize <span class="keyword">if</span> opts.historyFile
repl</pre></div></div>
</pre></div></div>
</li>

File diff suppressed because it is too large Load Diff

View File

@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -114,10 +114,19 @@ 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>
<p>Import the helpers we plan to use.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="p">{</span><span class="nx">extend</span><span class="p">,</span> <span class="nx">last</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<span class="nv">exports.Scope = </span><span class="k">class</span> <span class="nx">Scope</span></pre></div></div>
</li>
@@ -127,15 +136,15 @@ with external scopes.
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Import the helpers we plan to use.
<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="vi">@root: </span><span class="kc">null</span></pre></div></div>
</li>
@@ -146,13 +155,21 @@ exports.Scope = <span class="class"><span class="keyword">class</span> <span cla
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>The <code>root</code> is the top-level <strong>Scope</strong> object for a given file.
<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="nv">constructor: </span><span class="nf">(@parent, @expressions, @method) -&gt;</span>
<span class="vi">@variables = </span><span class="p">[{</span><span class="nv">name: </span><span class="s">&#39;arguments&#39;</span><span class="p">,</span> <span class="nv">type: </span><span class="s">&#39;arguments&#39;</span><span class="p">}]</span>
<span class="vi">@positions = </span><span class="p">{}</span>
<span class="nv">Scope.root = </span><span class="k">this</span> <span class="k">unless</span> <span class="nx">@parent</span></pre></div></div>
</li>
@@ -163,19 +180,20 @@ exports.Scope = <span class="class"><span class="keyword">class</span> <span cla
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</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>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>) -&gt;
<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="nv">add: </span><span class="nf">(name, type, immediate) -&gt;</span>
<span class="k">return</span> <span class="nx">@parent</span><span class="p">.</span><span class="nx">add</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">type</span><span class="p">,</span> <span class="nx">immediate</span> <span class="k">if</span> <span class="nx">@shared</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">immediate</span>
<span class="k">if</span> <span class="nb">Object</span><span class="o">::</span><span class="nx">hasOwnProperty</span><span class="p">.</span><span class="nx">call</span> <span class="nx">@positions</span><span class="p">,</span> <span class="nx">name</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">@positions</span><span class="p">[</span><span class="nx">name</span><span class="p">]].</span><span class="nv">type = </span><span class="nx">type</span>
<span class="k">else</span>
<span class="nx">@positions</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@variables</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">name</span><span class="p">,</span> <span class="nx">type</span><span class="p">})</span> <span class="o">-</span> <span class="mi">1</span></pre></div></div>
</li>
@@ -186,18 +204,21 @@ it belongs to.
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Adds a new variable or overrides an existing one.
<p>When <code>super</code> is called, we need to find the name of the current method we&#39;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) -&gt;
<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="nv">namedMethod: </span><span class="nf">-&gt;</span>
<span class="k">return</span> <span class="nx">@method</span> <span class="k">if</span> <span class="nx">@method</span><span class="o">?</span><span class="p">.</span><span class="nx">name</span> <span class="o">or</span> <span class="o">!</span><span class="nx">@parent</span>
<span class="nx">@parent</span><span class="p">.</span><span class="nx">namedMethod</span><span class="p">()</span></pre></div></div>
</li>
@@ -208,19 +229,19 @@ it belongs to.
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>When <code>super</code> is called, we need to find the name of the current method we&#39;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>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: -&gt;
<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="nv">find: </span><span class="nf">(name) -&gt;</span>
<span class="k">return</span> <span class="kc">yes</span> <span class="k">if</span> <span class="nx">@check</span> <span class="nx">name</span>
<span class="nx">@add</span> <span class="nx">name</span><span class="p">,</span> <span class="s">&#39;var&#39;</span>
<span class="kc">no</span></pre></div></div>
</li>
@@ -231,17 +252,18 @@ function object that has a name filled in, or bottoms out.
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Look up a variable name in lexical scope, and declare it if it does not
already exist.
<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) -&gt;
<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="nv">parameter: </span><span class="nf">(name) -&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@shared</span> <span class="o">and</span> <span class="nx">@parent</span><span class="p">.</span><span class="nx">check</span> <span class="nx">name</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nx">@add</span> <span class="nx">name</span><span class="p">,</span> <span class="s">&#39;param&#39;</span></pre></div></div>
</li>
@@ -252,16 +274,17 @@ already exist.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</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>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) -&gt;
<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="nv">check: </span><span class="nf">(name) -&gt;</span>
<span class="o">!!</span><span class="p">(</span><span class="nx">@type</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@parent</span><span class="o">?</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">name</span><span class="p">))</span></pre></div></div>
</li>
@@ -272,15 +295,19 @@ scope. No <code>var</code> required for internal references.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Just check to see if a variable has already been declared, without reserving,
walks up to the root scope.
<p>Generate a temporary variable name at the given index.
</p>
</div>
<div class="content"><div class='highlight'><pre>
check: (name) -&gt;
!!(<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="nv">temporary: </span><span class="nf">(name, index) -&gt;</span>
<span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="s">&#39;_&#39;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">index</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">index</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="s">&#39;&#39;</span>
<span class="k">else</span>
<span class="s">&#39;_&#39;</span> <span class="o">+</span> <span class="p">(</span><span class="nx">index</span> <span class="o">+</span> <span class="nb">parseInt</span> <span class="nx">name</span><span class="p">,</span> <span class="mi">36</span><span class="p">).</span><span class="nx">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nx">replace</span> <span class="sr">/\d/g</span><span class="p">,</span> <span class="s">&#39;a&#39;</span></pre></div></div>
</li>
@@ -291,17 +318,17 @@ walks up to the root scope.
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Generate a temporary variable name at the given index.
<p>Gets the type of a variable.
</p>
</div>
<div class="content"><div class='highlight'><pre>
temporary: (name, index) -&gt;
<span class="keyword">if</span> name.length &gt; <span class="number">1</span>
<span class="string">'_'</span> + name + <span class="keyword">if</span> index &gt; <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="nv">type: </span><span class="nf">(name) -&gt;</span>
<span class="k">return</span> <span class="nx">v</span><span class="p">.</span><span class="nx">type</span> <span class="k">for</span> <span class="nx">v</span> <span class="k">in</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">v</span><span class="p">.</span><span class="nx">name</span> <span class="o">is</span> <span class="nx">name</span>
<span class="kc">null</span></pre></div></div>
</li>
@@ -312,15 +339,20 @@ walks up to the root scope.
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Gets the type of a variable.
<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) -&gt;
<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="nv">freeVariable: </span><span class="nf">(name, reserve=true) -&gt;</span>
<span class="nv">index = </span><span class="mi">0</span>
<span class="nx">index</span><span class="o">++</span> <span class="k">while</span> <span class="nx">@check</span><span class="p">((</span><span class="nv">temp = </span><span class="nx">@temporary</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">index</span><span class="p">))</span>
<span class="nx">@add</span> <span class="nx">temp</span><span class="p">,</span> <span class="s">&#39;var&#39;</span><span class="p">,</span> <span class="kc">yes</span> <span class="k">if</span> <span class="nx">reserve</span>
<span class="nx">temp</span></pre></div></div>
</li>
@@ -331,18 +363,18 @@ walks up to the root scope.
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</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>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>) -&gt;
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="nv">assign: </span><span class="nf">(name, value) -&gt;</span>
<span class="nx">@add</span> <span class="nx">name</span><span class="p">,</span> <span class="p">{</span><span class="nx">value</span><span class="p">,</span> <span class="nv">assigned: </span><span class="kc">yes</span><span class="p">},</span> <span class="kc">yes</span>
<span class="vi">@hasAssignments = </span><span class="kc">yes</span></pre></div></div>
</li>
@@ -353,16 +385,16 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Ensure that an assignment is made at the top of this scope
(or at the top-level scope, if requested).
<p>Does this scope have any declared variables?
</p>
</div>
<div class="content"><div class='highlight'><pre>
assign: (name, value) -&gt;
<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="nv">hasDeclarations: </span><span class="nf">-&gt;</span>
<span class="o">!!</span><span class="nx">@declaredVariables</span><span class="p">().</span><span class="nx">length</span></pre></div></div>
</li>
@@ -373,14 +405,20 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Does this scope have any declared variables?
<p>Return the list of variables first declared in this scope.
</p>
</div>
<div class="content"><div class='highlight'><pre>
hasDeclarations: -&gt;
!!<span class="property">@declaredVariables</span>().length</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">declaredVariables: </span><span class="nf">-&gt;</span>
<span class="nv">realVars = </span><span class="p">[]</span>
<span class="nv">tempVars = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">v</span> <span class="k">in</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">v</span><span class="p">.</span><span class="nx">type</span> <span class="o">is</span> <span class="s">&#39;var&#39;</span>
<span class="p">(</span><span class="k">if</span> <span class="nx">v</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;_&#39;</span> <span class="k">then</span> <span class="nx">tempVars</span> <span class="k">else</span> <span class="nx">realVars</span><span class="p">).</span><span class="nx">push</span> <span class="nx">v</span><span class="p">.</span><span class="nx">name</span>
<span class="nx">realVars</span><span class="p">.</span><span class="nx">sort</span><span class="p">().</span><span class="nx">concat</span> <span class="nx">tempVars</span><span class="p">.</span><span class="nx">sort</span><span class="p">()</span></pre></div></div>
</li>
@@ -391,37 +429,18 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Return the list of variables first declared in this scope.
</p>
</div>
<div class="content"><div class='highlight'><pre>
declaredVariables: -&gt;
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">&#182;</a>
</div>
<p>Return the list of assignments that are supposed to be made at the top
<p>Return the list of assignments that are supposed to be made at the top
of this scope.
</p>
</div>
<div class="content"><div class='highlight'><pre>
assignedVariables: -&gt;
<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="nv">assignedVariables: </span><span class="nf">-&gt;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">v</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">v</span><span class="p">.</span><span class="nx">type</span><span class="p">.</span><span class="nx">value</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">for</span> <span class="nx">v</span> <span class="k">in</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">v</span><span class="p">.</span><span class="nx">type</span><span class="p">.</span><span class="nx">assigned</span>
</pre></div></div>
</li>

View File

@@ -2,7 +2,7 @@
<html>
<head>
<title>sourcemap.litcoffee</title>
<title>sourcemap.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" />
@@ -85,7 +85,7 @@
<a class="source" href="sourcemap.html">
sourcemap.litcoffee
sourcemap.coffee
</a>
</div>
@@ -96,7 +96,7 @@
<li id="title">
<div class="annotation">
<h1>sourcemap.litcoffee</h1>
<h1>sourcemap.coffee</h1>
</div>
</li>
@@ -108,14 +108,16 @@
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<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&#39;re concerned with mapping pretty-printed
JavaScript back to CoffeeScript.
<p>Hold data about mappings for one line of generated source code.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="k">class</span> <span class="nx">LineMapping</span>
<span class="nv">constructor: </span><span class="nf">(@generatedLine) -&gt;</span></pre></div></div>
</li>
@@ -125,28 +127,36 @@ JavaScript back to CoffeeScript.
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</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>columnMap keeps track of which columns we&#39;ve already mapped.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="vi">@columnMap = </span><span class="p">{}</span></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">&#182;</a>
</div>
<h2>LineMap</h2>
<p>columnMappings is an array of all column mappings, sorted by generated-column.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="vi">@columnMappings = </span><span class="p">[]</span>
<span class="nv">addMapping: </span><span class="nf">(generatedColumn, [sourceLine, sourceColumn], options={}) -&gt;</span>
<span class="k">if</span> <span class="nx">@columnMap</span><span class="p">[</span><span class="nx">generatedColumn</span><span class="p">]</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">noReplace</span></pre></div></div>
</li>
@@ -157,36 +167,60 @@ of this information — to write out alongside the generated JavaScript.
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>We already have a mapping for this column.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">return</span>
<span class="nx">@columnMap</span><span class="p">[</span><span class="nx">generatedColumn</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nv">generatedLine: </span><span class="nx">@generatedLine</span>
<span class="nx">generatedColumn</span>
<span class="nx">sourceLine</span>
<span class="nx">sourceColumn</span>
<span class="p">}</span>
<span class="nx">@columnMappings</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@columnMap</span><span class="p">[</span><span class="nx">generatedColumn</span><span class="p">]</span>
<span class="nx">@columnMappings</span><span class="p">.</span><span class="nx">sort</span> <span class="nf">(a,b) -&gt;</span> <span class="nx">a</span><span class="p">.</span><span class="nx">generatedColumn</span> <span class="o">-</span> <span class="nx">b</span><span class="p">.</span><span class="nx">generatedColumn</span>
<span class="nv">getSourcePosition: </span><span class="nf">(generatedColumn) -&gt;</span>
<span class="nv">answer = </span><span class="kc">null</span>
<span class="nv">lastColumnMapping = </span><span class="kc">null</span>
<span class="k">for</span> <span class="nx">columnMapping</span> <span class="k">in</span> <span class="nx">@columnMappings</span>
<span class="k">if</span> <span class="nx">columnMapping</span><span class="p">.</span><span class="nx">generatedColumn</span> <span class="o">&gt;</span> <span class="nx">generatedColumn</span>
<span class="k">break</span>
<span class="k">else</span>
<span class="nv">lastColumnMapping = </span><span class="nx">columnMapping</span>
<span class="k">if</span> <span class="nx">lastColumnMapping</span>
<span class="nv">answer = </span><span class="p">[</span><span class="nx">lastColumnMapping</span><span class="p">.</span><span class="nx">sourceLine</span><span class="p">,</span> <span class="nx">lastColumnMapping</span><span class="p">.</span><span class="nx">sourceColumn</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-5">&#182;</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>.
<h3>SourceMap</h3>
<p>Maps locations in a generated source file back to locations in the original source file.
</p>
<p>This is intentionally agnostic towards how a source map might be represented on disk. A
SourceMap can be converted to a &quot;v3&quot; style sourcemap with <code>#generateV3SourceMap()</code>, for example
but the SourceMap class itself knows nothing about v3 source maps.
</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>) -&gt;
<span class="property">@columns</span> = []
add: (column, [sourceLine, sourceColumn], options={}) -&gt;
<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) -&gt;
column-- <span class="keyword">until</span> (mapping = <span class="property">@columns</span>[column]) <span class="keyword">or</span> (column &lt;= <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="k">class</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">SourceMap</span>
<span class="nv">constructor: </span><span class="p">()</span> <span class="nf">-&gt;</span></pre></div></div>
</li>
@@ -194,13 +228,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">&#182;</a>
</div>
<h2>SourceMap</h2>
<p><code>generatedLines</code> is an array of LineMappings, one per generated line.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="vi">@generatedLines = </span><span class="p">[]</span></pre></div></div>
</li>
@@ -211,8 +250,28 @@ positions for a single line of output JavaScript code.
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Adds a mapping to this SourceMap.
</p>
<p><code>sourceLocation</code> and <code>generatedLocation</code> are both [line, column] arrays.
</p>
<p>If <code>options.noReplace</code> is true, then if there is already a mapping for
the specified <code>generatedLine</code> and <code>generatedColumn</code>, this will have no effect.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">addMapping: </span><span class="nf">(sourceLocation, generatedLocation, options={}) -&gt;</span>
<span class="p">[</span><span class="nx">generatedLine</span><span class="p">,</span> <span class="nx">generatedColumn</span><span class="p">]</span> <span class="o">=</span> <span class="nx">generatedLocation</span>
<span class="nv">lineMapping = </span><span class="nx">@generatedLines</span><span class="p">[</span><span class="nx">generatedLine</span><span class="p">]</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">lineMapping</span>
<span class="nv">lineMapping = </span><span class="nx">@generatedLines</span><span class="p">[</span><span class="nx">generatedLine</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">LineMapping</span><span class="p">(</span><span class="nx">generatedLine</span><span class="p">)</span>
<span class="nx">lineMapping</span><span class="p">.</span><span class="nx">addMapping</span> <span class="nx">generatedColumn</span><span class="p">,</span> <span class="nx">sourceLocation</span><span class="p">,</span> <span class="nx">options</span></pre></div></div>
</li>
@@ -222,12 +281,18 @@ positions for a single line of output JavaScript code.
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Maps locations in a single generated JavaScript file back to locations in
the original CoffeeScript source file.
<p>Returns [sourceLine, sourceColumn], or null if no mapping could be found.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">getSourcePosition: </span><span class="nf">([generatedLine, generatedColumn]) -&gt;</span>
<span class="nv">answer = </span><span class="kc">null</span>
<span class="nv">lineMapping = </span><span class="nx">@generatedLines</span><span class="p">[</span><span class="nx">generatedLine</span><span class="p">]</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">lineMapping</span></pre></div></div>
</li>
@@ -237,17 +302,17 @@ the original CoffeeScript source file.
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</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 &quot;v3&quot;-style source map, we can walk
through the arrays of line and column buffer to produce it.
<p>TODO: Search backwards for the 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: -&gt;
<span class="property">@lines</span> = []</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="k">else</span>
<span class="nv">answer = </span><span class="nx">lineMapping</span><span class="p">.</span><span class="nx">getSourcePosition</span> <span class="nx">generatedColumn</span>
<span class="nx">answer</span></pre></div></div>
</li>
@@ -258,19 +323,21 @@ through the arrays of line and column buffer to produce it.
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</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><code>fn</code> will be called once for every recorded mapping, in the order in
which they occur in the generated source. <code>fn</code> will be passed an object
with four properties: sourceLine, sourceColumn, generatedLine, and
generatedColumn.
</p>
</div>
<div class="content"><div class='highlight'><pre>
add: (sourceLocation, generatedLocation, options = {}) -&gt;
[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> <span class="nv">forEachMapping: </span><span class="nf">(fn) -&gt;</span>
<span class="k">for</span> <span class="nx">lineMapping</span><span class="p">,</span> <span class="nx">generatedLineNumber</span> <span class="k">in</span> <span class="nx">@generatedLines</span>
<span class="k">if</span> <span class="nx">lineMapping</span>
<span class="k">for</span> <span class="nx">columnMapping</span> <span class="k">in</span> <span class="nx">lineMapping</span><span class="p">.</span><span class="nx">columnMappings</span>
<span class="nx">fn</span><span class="p">(</span><span class="nx">columnMapping</span><span class="p">)</span></pre></div></div>
</li>
@@ -278,19 +345,34 @@ effect.
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Look up the original position of a given <code>line</code> and <code>column</code> in the generated
code.
<h3>generateV3SourceMap</h3>
<p>Builds a V3 source map from a SourceMap object.
Returns the generated JSON as a string.
</p>
</div>
<div class="content"><div class='highlight'><pre>
sourceLocation: ([line, column]) -&gt;
line-- <span class="keyword">until</span> (lineMap = <span class="property">@lines</span>[line]) <span class="keyword">or</span> (line &lt;= <span class="number">0</span>)
lineMap <span class="keyword">and</span> lineMap.sourceLocation column</pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.generateV3SourceMap = </span><span class="nf">(sourceMap, sourceFile=null, generatedFile=null) -&gt;</span>
<span class="nv">writingGeneratedLine = </span><span class="mi">0</span>
<span class="nv">lastGeneratedColumnWritten = </span><span class="mi">0</span>
<span class="nv">lastSourceLineWritten = </span><span class="mi">0</span>
<span class="nv">lastSourceColumnWritten = </span><span class="mi">0</span>
<span class="nv">needComma = </span><span class="kc">no</span>
<span class="nv">mappings = </span><span class="s">&quot;&quot;</span>
<span class="nx">sourceMap</span><span class="p">.</span><span class="nx">forEachMapping</span> <span class="nf">(mapping) -&gt;</span>
<span class="k">while</span> <span class="nx">writingGeneratedLine</span> <span class="o">&lt;</span> <span class="nx">mapping</span><span class="p">.</span><span class="nx">generatedLine</span>
<span class="nv">lastGeneratedColumnWritten = </span><span class="mi">0</span>
<span class="nv">needComma = </span><span class="kc">no</span>
<span class="nx">mappings</span> <span class="o">+=</span> <span class="s">&quot;;&quot;</span>
<span class="nx">writingGeneratedLine</span><span class="o">++</span></pre></div></div>
</li>
@@ -298,13 +380,20 @@ code.
<li id="section-12">
<div class="annotation">
<div class="pilwrap for-h2">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<h2>V3 SourceMap Generation</h2>
<p>Write a comma if we&#39;ve already written a segment on this line.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">needComma</span>
<span class="nx">mappings</span> <span class="o">+=</span> <span class="s">&quot;,&quot;</span>
<span class="nv">needComma = </span><span class="kc">no</span></pre></div></div>
</li>
@@ -315,8 +404,28 @@ code.
<a class="pilcrow" href="#section-13">&#182;</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&#39;t match anything in the source code.
</p>
<p>Fields are all zero-based, and relative to the previous occurence unless otherwise noted:
<em> starting-column in generated source, relative to previous occurence for the current line.
</em> index into the &quot;sources&quot; list
<em> starting line in the original source
</em> starting column in the original source
* index into the &quot;names&quot; list associated with this segment.
</p>
<p>Add the generated start-column
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nx">mappings</span> <span class="o">+=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">vlqEncodeValue</span><span class="p">(</span><span class="nx">mapping</span><span class="p">.</span><span class="nx">generatedColumn</span> <span class="o">-</span> <span class="nx">lastGeneratedColumnWritten</span><span class="p">)</span>
<span class="nv">lastGeneratedColumnWritten = </span><span class="nx">mapping</span><span class="p">.</span><span class="nx">generatedColumn</span></pre></div></div>
</li>
@@ -326,30 +435,14 @@ code.
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</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 &quot;sources&quot; and &quot;file&quot;, respectively.
<p>Add the index into the sources list
</p>
</div>
<div class="content"><div class='highlight'><pre>
generate: (options = {}, code = <span class="literal">null</span>) -&gt;
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>
<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 &lt; mapping.line
lastColumn = <span class="number">0</span>
needComma = <span class="literal">no</span>
buffer += <span class="string">";"</span>
writingline++</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nx">mappings</span> <span class="o">+=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">vlqEncodeValue</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></pre></div></div>
</li>
@@ -360,15 +453,15 @@ set &quot;sources&quot; and &quot;file&quot;, respectively.
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Write a comma if we&#39;ve already written a segment on this line.
<p>Add the source start-line
</p>
</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>
<div class="content"><div class="highlight"><pre> <span class="nx">mappings</span> <span class="o">+=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">vlqEncodeValue</span><span class="p">(</span><span class="nx">mapping</span><span class="p">.</span><span class="nx">sourceLine</span> <span class="o">-</span> <span class="nx">lastSourceLineWritten</span><span class="p">)</span>
<span class="nv">lastSourceLineWritten = </span><span class="nx">mapping</span><span class="p">.</span><span class="nx">sourceLine</span></pre></div></div>
</li>
@@ -379,12 +472,16 @@ set &quot;sources&quot; and &quot;file&quot;, respectively.
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</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&#39;t match anything in the source code.
<p>Add the source start-column
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nx">mappings</span> <span class="o">+=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">vlqEncodeValue</span><span class="p">(</span><span class="nx">mapping</span><span class="p">.</span><span class="nx">sourceColumn</span> <span class="o">-</span> <span class="nx">lastSourceColumnWritten</span><span class="p">)</span>
<span class="nv">lastSourceColumnWritten = </span><span class="nx">mapping</span><span class="p">.</span><span class="nx">sourceColumn</span></pre></div></div>
</li>
@@ -394,15 +491,26 @@ is a generated column which doesn&#39;t match anything in the source code.
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>The starting column in the generated source, relative to any previous recorded
column for the current line:
<p>TODO: Do we care about symbol names for CoffeeScript? Probably not.
</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> <span class="nv">needComma = </span><span class="kc">yes</span>
<span class="nv">answer = </span><span class="p">{</span>
<span class="nv">version: </span><span class="mi">3</span>
<span class="nv">file: </span><span class="nx">generatedFile</span>
<span class="nv">sourceRoot: </span><span class="s">&quot;&quot;</span>
<span class="nv">sources: </span><span class="k">if</span> <span class="nx">sourceFile</span> <span class="k">then</span> <span class="p">[</span><span class="nx">sourceFile</span><span class="p">]</span> <span class="k">else</span> <span class="p">[]</span>
<span class="nv">names: </span><span class="p">[]</span>
<span class="nx">mappings</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span> <span class="nx">answer</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">2</span></pre></div></div>
</li>
@@ -413,13 +521,15 @@ column for the current line:
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>The index into the list of sources:
<p>Load a SourceMap from a JSON string. Returns the SourceMap object.
</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><span class="nv">exports.loadV3SourceMap = </span><span class="nf">(sourceMap) -&gt;</span>
<span class="nx">todo</span><span class="p">()</span></pre></div></div>
</li>
@@ -427,17 +537,29 @@ column for the current line:
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>The starting line in the original source, relative to the previous source line.
</p>
<h3>Base64 encoding helpers</h3>
</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="nv">BASE64_CHARS = </span><span class="s">&#39;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#39;</span>
<span class="nv">MAX_BASE64_VALUE = </span><span class="nx">BASE64_CHARS</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">encodeBase64Char = </span><span class="nf">(value) -&gt;</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">&gt;</span> <span class="nx">MAX_BASE64_VALUE</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;Cannot encode value </span><span class="si">#{</span><span class="nx">value</span><span class="si">}</span><span class="s"> &gt; </span><span class="si">#{</span><span class="nx">MAX_BASE64_VALUE</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">&lt;</span> <span class="mi">0</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;Cannot encode value </span><span class="si">#{</span><span class="nx">value</span><span class="si">}</span><span class="s"> &lt; 0&quot;</span>
<span class="nx">BASE64_CHARS</span><span class="p">[</span><span class="nx">value</span><span class="p">]</span>
<span class="nv">decodeBase64Char = </span><span class="nf">(char) -&gt;</span>
<span class="nv">value = </span><span class="nx">BASE64_CHARS</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">char</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;Invalid Base 64 character: </span><span class="si">#{</span><span class="nx">char</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">value</span></pre></div></div>
</li>
@@ -445,18 +567,25 @@ column for the current line:
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>The starting column in the original source, relative to the previous column.
<h3>Base 64 VLQ encoding/decoding helpers</h3>
<p>Note that SourceMap VLQ encoding is &quot;backwards&quot;. 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">http://en.wikipedia.org/wiki/File:Uintvar_coding.svg</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>
buffer += <span class="property">@encodeVlq</span> mapping.sourceColumn - lastSourceColumn
lastSourceColumn = mapping.sourceColumn
needComma = <span class="literal">yes</span></pre></div></div>
<div class="content"><div class="highlight"><pre><span class="nv">VLQ_SHIFT = </span><span class="mi">5</span>
<span class="nv">VLQ_CONTINUATION_BIT = </span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="nx">VLQ_SHIFT</span> <span class="c1"># 0010 0000</span>
<span class="nv">VLQ_VALUE_MASK = </span><span class="nx">VLQ_CONTINUATION_BIT</span> <span class="o">-</span> <span class="mi">1</span> <span class="c1"># 0001 1111</span></pre></div></div>
</li>
@@ -467,23 +596,14 @@ column for the current line:
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Produce the canonical JSON object format for a &quot;v3&quot; source map.
<p>Encode a value as Base 64 VLQ.
</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
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>
<div class="content"><div class="highlight"><pre><span class="nv">exports.vlqEncodeValue = </span><span class="nf">(value) -&gt;</span></pre></div></div>
</li>
@@ -491,13 +611,18 @@ 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">&#182;</a>
</div>
<h2>Base64 VLQ Encoding</h2>
<p>Least significant bit represents the sign.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">signBit = </span><span class="k">if</span> <span class="nx">value</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="mi">1</span> <span class="k">else</span> <span class="mi">0</span></pre></div></div>
</li>
@@ -508,8 +633,16 @@ column for the current line:
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Next bits are the actual value
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">valueToEncode = </span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nx">signBit</span>
<span class="nv">answer = </span><span class="s">&quot;&quot;</span></pre></div></div>
</li>
@@ -519,22 +652,23 @@ column for the current line:
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Note that SourceMap VLQ encoding is &quot;backwards&quot;. 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>Make sure we encode at least one character, even if valueToEncode is 0.
</p>
</div>
<div class="content"><div class='highlight'><pre>
VLQ_SHIFT = <span class="number">5</span>
VLQ_CONTINUATION_BIT = <span class="number">1</span> &lt;&lt; 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>
<div class="content"><div class="highlight"><pre> <span class="k">while</span> <span class="nx">valueToEncode</span> <span class="o">||</span> <span class="o">!</span><span class="nx">answer</span>
<span class="nv">nextVlqChunk = </span><span class="nx">valueToEncode</span> <span class="o">&amp;</span> <span class="nx">VLQ_VALUE_MASK</span>
<span class="nv">valueToEncode = </span><span class="nx">valueToEncode</span> <span class="o">&gt;&gt;</span> <span class="nx">VLQ_SHIFT</span>
encodeVlq: (value) -&gt;
answer = <span class="string">''</span></pre></div></div>
<span class="k">if</span> <span class="nx">valueToEncode</span>
<span class="nx">nextVlqChunk</span> <span class="o">|=</span> <span class="nx">VLQ_CONTINUATION_BIT</span>
<span class="nx">answer</span> <span class="o">+=</span> <span class="nx">encodeBase64Char</span><span class="p">(</span><span class="nx">nextVlqChunk</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">answer</span></pre></div></div>
</li>
@@ -545,12 +679,32 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Least significant bit represents the sign.
<p>Decode a Base 64 VLQ value.
</p>
<p>Returns <code>[value, consumed]</code> where <code>value</code> is the decoded value, and <code>consumed</code> is the number
of characters consumed from <code>str</code>.
</p>
</div>
<div class="content"><div class='highlight'><pre> signBit = <span class="keyword">if</span> value &lt; <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>
<div class="content"><div class="highlight"><pre><span class="nv">exports.vlqDecodeValue = </span><span class="nf">(str, offset=0) -&gt;</span>
<span class="nv">position = </span><span class="nx">offset</span>
<span class="nv">done = </span><span class="kc">false</span>
<span class="nv">value = </span><span class="mi">0</span>
<span class="nv">continuationShift = </span><span class="mi">0</span>
<span class="k">while</span> <span class="o">!</span><span class="nx">done</span>
<span class="nv">nextVlqChunk = </span><span class="nx">decodeBase64Char</span><span class="p">(</span><span class="nx">str</span><span class="p">[</span><span class="nx">position</span><span class="p">])</span>
<span class="nx">position</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="nv">nextChunkValue = </span><span class="nx">nextVlqChunk</span> <span class="o">&amp;</span> <span class="nx">VLQ_VALUE_MASK</span>
<span class="nx">value</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">nextChunkValue</span> <span class="o">&lt;&lt;</span> <span class="nx">continuationShift</span><span class="p">)</span>
<span class="k">if</span> <span class="o">!</span><span class="p">(</span><span class="nx">nextVlqChunk</span> <span class="o">&amp;</span> <span class="nx">VLQ_CONTINUATION_BIT</span><span class="p">)</span></pre></div></div>
</li>
@@ -561,12 +715,14 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>The next bits are the actual value.
<p>We&#39;ll be done after this character.
</p>
</div>
<div class="content"><div class='highlight'><pre> valueToEncode = (Math.abs(value) &lt;&lt; <span class="number">1</span>) + signBit</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">done = </span><span class="kc">true</span></pre></div></div>
</li>
@@ -577,18 +733,17 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Make sure we encode at least one character, even if valueToEncode is 0.
<p>Bits are encoded least-significant first (opposite of MIDI VLQ). Increase the
continuationShift, so the next byte will end up where it should in the value.
</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 &amp; VLQ_VALUE_MASK
valueToEncode = valueToEncode &gt;&gt; VLQ_SHIFT
nextChunk |= VLQ_CONTINUATION_BIT <span class="keyword">if</span> valueToEncode
answer += <span class="property">@encodeBase64</span> nextChunk
<div class="content"><div class="highlight"><pre> <span class="nx">continuationShift</span> <span class="o">+=</span> <span class="nx">VLQ_SHIFT</span>
answer</pre></div></div>
<span class="nv">consumed = </span><span class="nx">position</span> <span class="o">-</span> <span class="nx">offset</span></pre></div></div>
</li>
@@ -596,47 +751,23 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
<li id="section-28">
<div class="annotation">
<div class="pilwrap for-h2">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</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">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre>
BASE64_CHARS = <span class="string">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'</span>
encodeBase64: (value) -&gt;
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">&#182;</a>
</div>
<p>Our API for source maps is just the <code>SourceMap</code> class.
<p>Least significant bit represents the sign.
</p>
</div>
<div class="content"><div class='highlight'><pre>
module.exports = SourceMap</pre></div></div>
<div class="content"><div class="highlight"><pre> <span class="nv">signBit = </span><span class="nx">value</span> <span class="o">&amp;</span> <span class="mi">1</span>
<span class="nv">value = </span><span class="nx">value</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">signBit</span> <span class="k">then</span> <span class="nv">value = </span><span class="o">-</span><span class="nx">value</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">value</span><span class="p">,</span> <span class="nx">consumed</span><span class="p">]</span>
</pre></div></div>
</li>

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,29 @@
<%
require 'uv'
require 'json'
@counter = 0
def code_for(file, executable=false, show_load=true)
@counter += 1
return '' unless File.exists?("documentation/js/#{file}.js")
cs = File.read("documentation/coffee/#{file}.coffee")
js = File.read("documentation/js/#{file}.js")
js = js.sub(/^\/\/ generated.*?\n/i, '')
cshtml = Uv.parse(cs, 'xhtml', 'coffeescript', false, 'idle', false)
jshtml = Uv.parse(js, 'xhtml', 'javascript', false, 'idle', false)
append = executable == true ? '' : "alert(#{executable});"
if executable and executable != true
cs.sub!(/(\S)\s*\Z/m, "\\1\n\nalert #{executable}")
end
run = executable == true ? 'run' : "run: #{executable}"
name = "example#{@counter}"
script = "<script>window.#{name} = #{cs.to_json}</script>"
import = show_load ? "<div class='minibutton load' onclick='javascript: loadConsole(#{name});'>load</div>" : ''
button = executable ? "<div class='minibutton ok' onclick='javascript: #{js};#{append}'>#{run}</div>" : ''
"<div class='code'>#{cshtml}#{jshtml}#{script}#{import}#{button}<br class='clear' /></div>"
end
%>
<!DOCTYPE html>
<html>
<head>
@@ -5,7 +31,7 @@
<title>CoffeeScript</title>
<link rel="canonical" href="http://coffeescript.org" />
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/tomorrow.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
<link rel="shortcut icon" href="documentation/images/favicon.ico" />
</head>
<body>
@@ -105,13 +131,15 @@
compiles one-to-one into the equivalent JS, and there is
no interpretation at runtime. You can use any existing JavaScript library
seamlessly from CoffeeScript (and vice-versa). The compiled output is
readable and pretty-printed, will work in every JavaScript runtime, and tends
readable and pretty-printed, passes through
<a href="http://www.javascriptlint.com/">JavaScript Lint</a>
without warnings, will work in every JavaScript runtime, and tends
to run as fast or faster than the equivalent handwritten JavaScript.
</p>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.7.0">1.7.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.6.1">1.6.1</a>
</p>
<pre>
@@ -124,7 +152,7 @@ sudo npm install -g coffee-script</pre>
<p><i>CoffeeScript on the left, compiled JavaScript output on the right.</i></p>
<%= codeFor('overview', 'cubes', false) %>
<%= code_for('overview', 'cubes', false) %>
<h2>
<span id="installation" class="bookmark"></span>
@@ -238,6 +266,16 @@ sudo bin/cake install</pre>
directly to <b>stdout</b>.
</td>
</tr>
<tr>
<td><code>-l, --lint</code></td>
<td>
If the <tt>jsl</tt>
(<a href="http://www.javascriptlint.com/">JavaScript Lint</a>)
command is installed, use it
to check the compilation of a CoffeeScript file. (Handy in
conjunction with <br /> <tt>--watch</tt>)
</td>
</tr>
<tr>
<td><code>-s, --stdio</code></td>
<td>
@@ -246,14 +284,6 @@ sudo bin/cake install</pre>
<tt>cat src/cake.coffee | coffee -sc</tt>
</td>
</tr>
<tr>
<td><code>-l, --literate</code></td>
<td>
Parses the code as Literate CoffeeScript. You only need to specify
this when passing in code directly over <b>stdio</b>, or using some sort
of extension-less file name.
</td>
</tr>
<tr>
<td><code>-e, --eval</code></td>
<td>
@@ -261,6 +291,13 @@ sudo bin/cake install</pre>
command line. For example:<br /><tt>coffee -e "console.log num for num in [10..1]"</tt>
</td>
</tr>
<tr>
<td><code>-r, --require</code></td>
<td>
Load a library before compiling or executing your script. Can be used
to hook in to the compiler (to add Growl notifications, for example).
</td>
</tr>
<tr>
<td><code>-b, --bare</code></td>
<td>
@@ -409,12 +446,12 @@ Expressions
an arrow, and the function body. The empty function looks like this:
<tt>-></tt>
</p>
<%= codeFor('functions', 'cube(5)') %>
<%= code_for('functions', 'cube(5)') %>
<p>
Functions may also have default values for arguments, which will be used
if the incoming argument is missing (<tt>null</tt> or <tt>undefined</tt>).
Functions may also have default values for arguments. Override the default
value by passing a non-null argument.
</p>
<%= codeFor('default_args', 'fill("cup")') %>
<%= code_for('default_args', 'fill("cup")') %>
<p>
<span id="objects_and_arrays" class="bookmark"></span>
@@ -424,14 +461,14 @@ Expressions
the commas are optional. Objects may be created using indentation instead
of explicit braces, similar to <a href="http://yaml.org">YAML</a>.
</p>
<%= codeFor('objects_and_arrays', 'song.join(" ... ")') %>
<%= code_for('objects_and_arrays', 'song.join(" ... ")') %>
<p>
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
of an object, without quoting them as strings. CoffeeScript notices reserved words
used as keys in objects and quotes them for you, so you don't have to worry
about it (say, when using jQuery).
</p>
<%= codeFor('objects_reserved') %>
<%= code_for('objects_reserved') %>
<p>
<span id="lexical-scope" class="bookmark"></span>
@@ -440,7 +477,7 @@ Expressions
are properly declared within lexical scope &mdash; you never need to write
<tt>var</tt> yourself.
</p>
<%= codeFor('scope', 'inner') %>
<%= code_for('scope', 'inner') %>
<p>
Notice how all of the variable declarations have been pushed up to
the top of the closest scope, the first time they appear.
@@ -485,7 +522,7 @@ Expressions
is no explicit ternary statement in CoffeeScript &mdash; you simply use
a regular <b>if</b> statement on a single line.
</p>
<%= codeFor('conditionals') %>
<%= code_for('conditionals') %>
<p>
<span id="splats" class="bookmark"></span>
@@ -495,7 +532,7 @@ Expressions
splats <tt>...</tt>, both for function definition as well as invocation,
making variable numbers of arguments a little bit more palatable.
</p>
<%= codeFor('splats', true) %>
<%= code_for('splats', true) %>
<p>
<span id="loops" class="bookmark"></span>
@@ -506,7 +543,7 @@ Expressions
Unlike for loops, array comprehensions are expressions, and can be returned
and assigned.
</p>
<%= codeFor('array_comprehensions') %>
<%= code_for('array_comprehensions') %>
<p>
Comprehensions should be able to handle most places where you otherwise
would use a loop, <b>each</b>/<b>forEach</b>, <b>map</b>, or <b>select</b>/<b>filter</b>, for example:
@@ -515,7 +552,7 @@ Expressions
in fixed-size increments, you can use a range to specify the start and
end of your comprehension.
</p>
<%= codeFor('range_comprehensions', 'countdown') %>
<%= code_for('range_comprehensions', 'countdown') %>
<p>
Note how because we are assigning the value of the comprehensions to a
variable in the example above, CoffeeScript is collecting the result of
@@ -535,7 +572,7 @@ Expressions
an object. Use <tt>of</tt> to signal comprehension over the properties of
an object instead of the values in an array.
</p>
<%= codeFor('object_comprehensions', 'ages.join(", ")') %>
<%= code_for('object_comprehensions', 'ages.join(", ")') %>
<p>
If you would like to iterate over just the keys that are defined on the
object itself, by adding a <tt>hasOwnProperty</tt>
@@ -548,7 +585,7 @@ Expressions
as an expression, returning an array containing the result of each iteration
through the loop.
</p>
<%= codeFor('while', 'lyrics.join("\n")') %>
<%= code_for('while', 'lyrics.join("\n")') %>
<p>
For readability, the <b>until</b> keyword is equivalent to <tt>while not</tt>,
and the <b>loop</b> keyword is equivalent to <tt>while true</tt>.
@@ -560,7 +597,7 @@ Expressions
provides the <tt>do</tt> keyword, which immediately invokes a passed function,
forwarding any arguments.
</p>
<%= codeFor('do') %>
<%= code_for('do') %>
<p>
<span id="slices" class="bookmark"></span>
@@ -571,12 +608,12 @@ Expressions
Slices indices have useful defaults. An omitted first index defaults to
zero and an omitted second index defaults to the size of the array.
</p>
<%= codeFor('slices', 'middle') %>
<%= code_for('slices', 'middle') %>
<p>
The same syntax can be used with assignment to replace a segment of an array
with new values, splicing it.
</p>
<%= codeFor('splices', 'numbers') %>
<%= code_for('splices', 'numbers') %>
<p>
Note that JavaScript strings are immutable, and can't be spliced.
</p>
@@ -590,7 +627,7 @@ Expressions
pushed down into each possible branch of execution in the function
below.
</p>
<%= codeFor('expressions', 'eldest') %>
<%= code_for('expressions', 'eldest') %>
<p>
Even though functions will always return their final value, it's both possible
and encouraged to return early from a function body writing out the explicit
@@ -600,19 +637,19 @@ Expressions
Because variable declarations occur at the top of scope, assignment can
be used within expressions, even for variables that haven't been seen before:
</p>
<%= codeFor('expressions_assignment', 'six') %>
<%= code_for('expressions_assignment', 'six') %>
<p>
Things that would otherwise be statements in JavaScript, when used
as part of an expression in CoffeeScript, are converted into expressions
by wrapping them in a closure. This lets you do useful things, like assign
the result of a comprehension to a variable:
</p>
<%= codeFor('expressions_comprehension', 'globals') %>
<%= code_for('expressions_comprehension', 'globals') %>
<p>
As well as silly things, like passing a <b>try/catch</b> statement directly
into a function call:
</p>
<%= codeFor('expressions_try', true) %>
<%= code_for('expressions_try', true) %>
<p>
There are a handful of statements in JavaScript that can't be meaningfully
converted into expressions, namely <tt>break</tt>, <tt>continue</tt>,
@@ -656,9 +693,7 @@ Expressions
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
test for JavaScript object-key presence.
</p>
<p>
To simplify math expressions, `**` can be used for exponentiation, `//` performs integer division and `%%` provides true mathematical modulo.
</p>
<p>
All together now:
</p>
@@ -675,12 +710,9 @@ Expressions
<tr><td><tt>@, this</tt></td><td><tt>this</tt></td></tr>
<tr><td><tt>of</tt></td><td><tt>in</tt></td></tr>
<tr><td><tt>in</tt></td><td><i><small>no JS equivalent</small></i></td></tr>
<tr><td><tt>a ** b</tt></td><td><tt>Math.pow(a, b)</tt></td></tr>
<tr><td><tt>a // b</tt></td><td><tt>Math.floor(a / b)</tt></td></tr>
<tr><td><tt>a %% b</tt></td><td><tt>(a % b + b) % b</tt></td></tr>
</table>
<%= codeFor('aliases') %>
<%= code_for('aliases') %>
<p>
<b class="header">The Existential Operator</b>
@@ -694,7 +726,7 @@ Expressions
It can also be used for safer conditional assignment than <tt>||=</tt>
provides, for cases where you may be handling numbers or strings.
</p>
<%= codeFor('existence', 'footprints') %>
<%= code_for('existence', 'footprints') %>
<p>
The accessor variant of the existential operator <tt>?.</tt> can be used to soak
up null references in a chain of properties. Use it instead
@@ -703,7 +735,7 @@ Expressions
result, if the chain is broken, <b>undefined</b> is returned instead of
the <b>TypeError</b> that would be raised otherwise.
</p>
<%= codeFor('soaks') %>
<%= code_for('soaks') %>
<p>
Soaking up nulls is similar to Ruby's
<a href="http://andand.rubyforge.org/">andand gem</a>, and to the
@@ -736,7 +768,7 @@ Expressions
Constructor functions are named, to better support helpful stack traces.
In the first class in the example below, <tt>this.constructor.name is "Animal"</tt>.
</p>
<%= codeFor('classes', true) %>
<%= code_for('classes', true) %>
<p>
If structuring your prototypes classically isn't your cup of tea, CoffeeScript
provides a couple of lower-level conveniences. The <tt>extends</tt> operator
@@ -745,7 +777,7 @@ Expressions
quick access to an object's prototype; and <tt>super()</tt>
is converted into a call against the immediate ancestor's method of the same name.
</p>
<%= codeFor('prototypes', '"one_two".dasherize()') %>
<%= code_for('prototypes', '"one_two".dasherize()') %>
<p>
Finally, class definitions are blocks of executable code, which make for interesting
metaprogramming possibilities. Because in the context of a class definition,
@@ -765,30 +797,21 @@ Expressions
on the right to the variables on the left. In the simplest case, it can be
used for parallel assignment:
</p>
<%= codeFor('parallel_assignment', 'theBait') %>
<%= code_for('parallel_assignment', 'theBait') %>
<p>
But it's also helpful for dealing with functions that return multiple
values.
</p>
<%= codeFor('multiple_return_values', 'forecast') %>
<%= code_for('multiple_return_values', 'forecast') %>
<p>
Destructuring assignment can be used with any depth of array and object nesting,
to help pull out deeply nested properties.
</p>
<%= codeFor('object_extraction', '"name + "-" + street"') %>
<%= code_for('object_extraction', 'name + "" + street') %>
<p>
Destructuring assignment can even be combined with splats.
</p>
<%= codeFor('patterns_and_splats', 'contents.join("")') %>
<p>
Expansion can be used to retrieve elements from the end of an array without having to assign the rest of its values. It works in function parameter lists as well.
</p>
<%= codeFor('expansion', '"first + " " + last"') %>
<p>
Destructuring assignment is also useful when combined with class constructors
to assign properties to your instance from an options object passed to the constructor.
</p>
<%= codeFor('constructor_destructuring', 'tim.age') %>
<%= code_for('patterns_and_splats', 'contents.join("")') %>
<p>
<span id="fat-arrow" class="bookmark"></span>
@@ -808,7 +831,7 @@ Expressions
to use with <tt>bind</tt>. Functions created with the fat arrow are able to access
properties of the <tt>this</tt> where they're defined.
</p>
<%= codeFor('fat_arrow') %>
<%= code_for('fat_arrow') %>
<p>
If we had used <tt>-&gt;</tt> in the callback above, <tt>@customer</tt> would
have referred to the undefined "customer" property of the DOM element,
@@ -827,7 +850,7 @@ Expressions
snippets of JavaScript within your CoffeeScript, you can
use backticks to pass it straight through.
</p>
<%= codeFor('embedded', 'hi()') %>
<%= code_for('embedded', 'hi()') %>
<p>
<span id="switch" class="bookmark"></span>
@@ -844,12 +867,7 @@ Expressions
values for each <b>when</b> clause. If any of the values match, the clause
runs.
</p>
<%= codeFor('switch') %>
<p>
Switch statements can also be used without a control expression, turning them in to a cleaner alternative to if/else chains.
</p>
<%= codeFor('switch_with_no_expression') %>
<%= code_for('switch') %>
<p>
<span id="try" class="bookmark"></span>
@@ -857,7 +875,7 @@ Expressions
Try/catch statements are just about the same as JavaScript (although
they work as expressions).
</p>
<%= codeFor('try') %>
<%= code_for('try') %>
<p>
<span id="comparisons" class="bookmark"></span>
@@ -867,7 +885,7 @@ Expressions
from Python &mdash; making it easy to test if a value falls within a
certain range.
</p>
<%= codeFor('comparisons', 'healthy') %>
<%= code_for('comparisons', 'healthy') %>
<p>
<span id="strings" class="bookmark"></span>
@@ -876,18 +894,18 @@ Expressions
strings allow for interpolated values, using <tt>#{ ... }</tt>,
and single-quoted strings are literal.
</p>
<%= codeFor('interpolation', 'sentence') %>
<%= code_for('interpolation', 'sentence') %>
<p>
Multiline strings are allowed in CoffeeScript. Lines are joined by a single space unless they end with a backslash. Indentation is ignored.
Multiline strings are allowed in CoffeeScript.
</p>
<%= codeFor('strings', 'mobyDick') %>
<%= code_for('strings', 'mobyDick') %>
<p>
Block strings can be used to hold formatted or indentation-sensitive text
(or, if you just don't feel like escaping quotes and apostrophes). The
indentation level that begins the block is maintained throughout, so
you can keep it all aligned with the body of your code.
</p>
<%= codeFor('heredocs', 'html') %>
<%= code_for('heredocs', 'html') %>
<p>
Double-quoted block strings, like other double-quoted strings, allow interpolation.
</p>
@@ -897,18 +915,18 @@ Expressions
the top of a file. Block comments, which mirror the syntax for block strings,
are preserved in the generated code.
</p>
<%= codeFor('block_comment') %>
<%= code_for('block_comment') %>
<p>
<span id="regexes" class="bookmark"></span>
<b class="header">Block Regular Expressions</b>
Similar to block strings and comments, CoffeeScript supports block regexes &mdash;
extended regular expressions that ignore internal whitespace and can contain
comments and interpolation. Modeled after Perl's <tt>/x</tt> modifier, CoffeeScript's
comments and interpolation. Modeled after Perl's <tt>/x</tt> modifier, CoffeeSctipt's
block regexes are delimited by <tt>///</tt> and go a long way towards making complex
regular expressions readable. To quote from the CoffeeScript source:
</p>
<%= codeFor('heregexes') %>
<%= code_for('heregexes') %>
<h2>
@@ -934,7 +952,7 @@ Expressions
be made available in the <tt>options</tt> object. Here's a task that uses
the Node.js API to rebuild CoffeeScript's parser:
</p>
<%= codeFor('cake_tasks') %>
<%= code_for('cake_tasks') %>
<p>
If you need to invoke one task before another &mdash; for example, running
<tt>build</tt> before <tt>test</tt>, you can use the <tt>invoke</tt> function:
@@ -1042,16 +1060,6 @@ Expressions
is a succinct and freely downloadable guide to building testable
applications with CoffeeScript and Jasmine.
</li>
<li>
<a href="http://www.packtpub.com/coffeescript-application-development/book">CoffeeScript Application Development</a>
is a new book from Packt Publishing that introduces CoffeeScript while
walking through the process of building a demonstration web application.
</li>
<li>
<a href="http://www.manning.com/lee/">CoffeeScript in Action</a>
is a new book from Manning Publications that covers CoffeeScript syntax, composition techniques
and application development.
</li>
</ul>
<h2>
@@ -1157,13 +1165,6 @@ Expressions
<a href="http://github.com/jashkenas/coffee-script/wiki/FAQ">The FAQ</a><br />
Perhaps your CoffeeScript-related question has been asked before. Check the FAQ first.
</li>
<li>
<a href="http://js2coffee.org">JS2Coffee</a><br />
Is a very well done reverse JavaScript-to-CoffeeScript compiler. It's
not going to be perfect (infer what your JavaScript classes are, when
you need bound functions, and so on...) &mdash; but it's a great starting
point for converting simple scripts.
</li>
<li>
<a href="https://github.com/jashkenas/coffee-script/downloads">High-Rez Logo</a><br />
The CoffeeScript logo is available in Illustrator, EPS and PSD formats, for use
@@ -1191,105 +1192,6 @@ Expressions
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.6.3...1.7.0">1.7.0</a>
<span class="timestamp"> &ndash; <small>January 28, 2014</small></span>
</b>
<ul>
<li>
When requiring CoffeeScript files in Node you must now explicitly register the compiler. This can be done with <tt>require 'coffee-script/register'</tt> or <tt>CoffeeScript.register()</tt>. Also for configuration such as Mocha's, use <b>coffee-script/register</b>.
</li>
<li>
Improved error messages, source maps and stack traces. Source maps now use the updated <tt>//#</tt> syntax.
</li>
<li>
Leading <tt>.</tt> now closes all open calls, allowing for simpler chaining syntax.
</li>
</ul>
<%= codeFor('chaining') %>
<ul>
<li>
Added <tt>**</tt>, <tt>//</tt> and <tt>%%</tt> operators and <tt>...</tt> expansion in paramater lists and destructuring expressions.
</li>
<li>
Multiline strings are now joined by a single space and ignore all indentation. A backslash at the end of a line can denote the amount of whitespace between lines, in both strings and heredocs. Backslashes correctly escape whitespace in block regexes.
</li>
<li>
Closing brackets can now be indented and therefore no longer cause unexpected error.
</li>
<li>
Several breaking compilation fixes. Non-callable literals (strings, numbers etc.) don't compile in a call now and multiple postfix conditionals compile properly. Postfix conditionals and loops always bind object literals. Conditional assignment compiles properly in subexpressions. <tt>super</tt> is disallowed outside of methods and works correctly inside <tt>for</tt> loops.
</li>
<li>
Formatting of compiled block comments has been improved.
</li>
<li>
No more <tt>-p</tt> folders on Windows.
</li>
<li>
The <tt>options</tt> object passed to CoffeeScript is no longer mutated.
</li>
</ul>
</p>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.6.2...1.6.3">1.6.3</a>
<span class="timestamp"> &ndash; <small>June 2, 2013</small></span>
</b>
<ul>
<li>
The CoffeeScript REPL now remembers your history between sessions.
Just like a proper REPL should.
</li>
<li>
You can now use <tt>require</tt> in Node to load <tt>.coffee.md</tt>
Literate CoffeeScript files. In the browser,
<tt>text/literate-coffeescript</tt> script tags.
</li>
<li>
The old <tt>coffee --lint</tt> command has been removed. It was useful
while originally working on the compiler, but has been surpassed by
JSHint. You may now use <tt>-l</tt> to pass literate files in over
<b>stdio</b>.
</li>
<li>
Bugfixes for Windows path separators, <tt>catch</tt> without naming
the error, and executable-class-bodies-with-
prototypal-property-attachment.
</li>
</ul>
</p>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.6.1...1.6.2">1.6.2</a>
<span class="timestamp"> &ndash; <small>March 18, 2013</small></span>
</b>
<ul>
<li>
Source maps have been used to provide automatic line-mapping when
running CoffeeScript directly via the <tt>coffee</tt> command, and
for automatic line-mapping when running CoffeeScript directly in the
browser. Also, to provide better error messages for semantic errors
thrown by the compiler &mdash;
<a href="http://cl.ly/NdOA">with colors, even</a>.
</li>
<li>
Improved support for mixed literate/vanilla-style CoffeeScript projects,
and generating source maps for both at the same time.
</li>
<li>
Fixes for <b>1.6.x</b> regressions with overriding inherited bound
functions, and for Windows file path management.
</li>
<li>
The <tt>coffee</tt> command can now correctly <tt>fork()</tt>
both <tt>.coffee</tt> and <tt>.js</tt> files. (Requires Node.js 0.9+)
</li>
</ul>
</p>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.5.0...1.6.1">1.6.1</a>
@@ -2037,10 +1939,8 @@ Expressions
else
$(el).text window.compiledJS
$('#error').hide()
catch {location, message}
if location?
message = "Error on line #{location.first_line + 1}: #{message}"
$('#error').text(message).show()
catch error
$('#error').text(error.message).show()
# Update permalink
$('#repl_permalink').attr 'href', "##{sourceFragment}#{encodeURIComponent source}"

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var volume, winner;
if (ignition === true) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var courses, dish, food, foods, i, _i, _j, _k, _len, _len1, _len2, _ref;
_ref = ['toast', 'cheese', 'wine'];

View File

@@ -1,7 +1,7 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
/*
SkinnyMochaHalfCaffScript Compiler v1.0
CoffeeScript Compiler v1.6.1
Released under the MIT License
*/
*/

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var fs;
fs = require('fs');

View File

@@ -1,4 +0,0 @@
// Generated by CoffeeScript 1.7.0
$('body').click(function(e) {
return $('.box').fadeIn('fast').addClass('.active');
}).css('background', 'white');

View File

@@ -1,9 +1,10 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var Animal, Horse, Snake, sam, tom,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Animal = (function() {
function Animal(name) {
this.name = name;
}
@@ -17,6 +18,7 @@ Animal = (function() {
})();
Snake = (function(_super) {
__extends(Snake, _super);
function Snake() {
@@ -33,6 +35,7 @@ Snake = (function(_super) {
})(Animal);
Horse = (function(_super) {
__extends(Horse, _super);
function Horse() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var cholesterol, healthy;
cholesterol = 127;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var date, mood;
if (singing) {

View File

@@ -1,15 +0,0 @@
// Generated by CoffeeScript 1.7.0
var Person, tim;
Person = (function() {
function Person(options) {
this.name = options.name, this.age = options.age, this.height = options.height;
}
return Person;
})();
tim = new Person({
age: 4
});

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var fill;
fill = function(container, liquid) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var filename, _fn, _i, _len;
_fn = function(filename) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var hi;
hi = function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var footprints, solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && (typeof world === "undefined" || world === null)) {

View File

@@ -1,6 +0,0 @@
// Generated by CoffeeScript 1.7.0
var first, last, text, _ref;
text = "Every literary critic believes he will outwit history and have the last word";
_ref = text.split(" "), first = _ref[0], last = _ref[_ref.length - 1];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var eldest, grade;
grade = function(student) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var one, six, three, two;
six = (one = 1) + (two = 2) + (three = 3);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var globals, name;
globals = ((function() {

View File

@@ -1,11 +1,9 @@
// Generated by CoffeeScript 1.7.0
var error;
// Generated by CoffeeScript 1.6.1
alert((function() {
try {
return nonexistent / void 0;
} catch (_error) {
error = _error;
} catch (error) {
return "And the error is ... " + error;
}
})());

View File

@@ -1,12 +1,11 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var Account;
Account = function(customer, cart) {
var _this = this;
this.customer = customer;
this.cart = cart;
return $('.shopping_cart').bind('click', (function(_this) {
return function(event) {
return _this.customer.purchase(_this.cart);
};
})(this));
return $('.shopping_cart').bind('click', function(event) {
return _this.customer.purchase(_this.cart);
});
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var cube, square;
square = function(x) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var html;
html = "<strong>\n cup of coffeescript\n</strong>";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var OPERATOR;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var author, quote, sentence;
author = "Wittgenstein";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var city, forecast, temp, weatherReport, _ref;
weatherReport = function(location) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var age, ages, child, yearsOld;
yearsOld = {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var city, futurists, name, street, _ref, _ref1;
futurists = {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var bitlist, kids, singers, song;
song = ["do", "re", "mi", "fa", "so"];

View File

@@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
$('.account').attr({
"class": 'active'
});

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var cubes, list, math, num, number, opposite, race, square,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var theBait, theSwitch, _ref;
theBait = 1000;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var close, contents, open, tag, _i, _ref,
__slice = [].slice;

View File

@@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var countdown, num;
countdown = (function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var changeNumbers, inner, outer;
outer = 1;

View File

@@ -1,12 +1,12 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var copy, end, middle, numbers, start;
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
start = numbers.slice(0, 3);
middle = numbers.slice(3, -2);
middle = numbers.slice(3, 6);
end = numbers.slice(-2);
end = numbers.slice(6);
copy = numbers.slice(0);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var zip, _ref;
zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var awardMedals, contenders, gold, rest, silver,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var numbers, _ref;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var mobyDick;
mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";

View File

@@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
switch (day) {
case "Mon":
go(work);

View File

@@ -1,19 +0,0 @@
// Generated by CoffeeScript 1.7.0
var grade, score;
score = 76;
grade = (function() {
switch (false) {
case !(score < 60):
return 'F';
case !(score < 70):
return 'D';
case !(score < 80):
return 'C';
case !(score < 90):
return 'B';
default:
return 'A';
}
})();

View File

@@ -1,11 +1,9 @@
// Generated by CoffeeScript 1.7.0
var error;
// Generated by CoffeeScript 1.6.1
try {
allHellBreaksLoose();
catsAndDogsLivingTogether();
} catch (_error) {
error = _error;
} catch (error) {
print(error);
} finally {
cleanUp();

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
var lyrics, num;
if (this.studyingEconomics) {
@@ -16,7 +16,7 @@ lyrics = (function() {
var _results;
_results = [];
while (num -= 1) {
_results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
_results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
}
return _results;
})();

View File

@@ -31,7 +31,7 @@ File.open = (path, mode, block) ->
# Write.
write = (location, data) ->
path = new Pathname location
throw new Error "Location does not exist" unless fs.existsSync location
throw new Error "Location does not exist" unless fs.existsSync(location)
File.open path, 'w', (file) ->
return false if Digest.MD5.hexdigest(file.read()) is data.hash()

View File

@@ -13,7 +13,7 @@ run_loop = ->
wait()
# Objects:
dense_object_literal = one: 1, two: 2, three: 3
dense_object_literal = {one: 1, two: 2, three: 3}
spaced_out_multiline_object =
pi: 3.14159
@@ -56,7 +56,7 @@ race = ->
run()
walk()
crawl()
return sleep() if tired
if tired then return sleep()
race()
# Conditional assignment:
@@ -64,7 +64,7 @@ good or= evil
wine and= cheese
# Nested property access and calls.
(moon.turn 360).shapes[3].move(x: 45, y: 30).position['top'].offset('x')
((moon.turn(360))).shapes[3].move({x: 45, y: 30}).position['top'].offset('x')
a = b = c = 5
@@ -79,7 +79,7 @@ try
dogs_and_cats_living_together()
throw "up"
catch error
print error
print(error)
finally
clean_up()
@@ -130,8 +130,8 @@ wednesday = -> eat_breakfast(); go_to_work(); eat_dinner()
# Multiline strings with inner quotes.
story = "Lorem ipsum dolor \"sit\" amet, consectetuer adipiscing elit,
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
aliquam erat volutpat. Ut wisi enim ad."
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
aliquam erat volutpat. Ut wisi enim ad."
# Inheritance and calling super.
class Animal

View File

@@ -19,7 +19,7 @@ binary_search = (items, value) ->
# Test the function.
console.log 2 is binary_search [10, 20, 30, 40, 50], 30
console.log 4 is binary_search [-97, 35, 67, 88, 1200], 1200
console.log 0 is binary_search [0, 45, 70], 0
console.log -1 is binary_search [0, 45, 70], 10
console.log 2 is binary_search [10, 20, 30, 40, 50], 30
console.log 4 is binary_search [-97, 35, 67, 88, 1200], 1200
console.log 0 is binary_search [0, 45, 70], 0
console.log(-1 is binary_search [0, 45, 70], 10)

View File

@@ -1,8 +1,8 @@
# A bubble sort implementation, sorting the given array in-place.
bubble_sort = (list) ->
for i in [0...list.length]
for j in [0...list.length - i] when list[j] > list[j + 1]
[list[j], list[j+1]] = [list[j + 1], list[j]]
for j in [0...list.length - i]
[list[j], list[j+1]] = [list[j+1], list[j]] if list[j] > list[j+1]
list

View File

@@ -1,8 +1,8 @@
# "Classic" linked list implementation that doesn't keep track of its size.
class LinkedList
constructor: ->
@_head = null # Pointer to the first item in the list.
->
this._head = null # Pointer to the first item in the list.
# Appends some data to the end of the list. This method traverses the existing
@@ -12,10 +12,10 @@ class LinkedList
# Create a new node object to wrap the data.
node = data: data, next: null
current = @_head or= node
current = this._head or= node
if @_head isnt node
current = current.next while current.next
if this._head isnt node
(current = current.next) while current.next
current.next = node
this
@@ -27,11 +27,11 @@ class LinkedList
# Check for out-of-bounds values.
return null if index < 0
current = @_head or null
current = this._head or null
i = -1
# Advance through the list.
current = current.next while current and index > ++i
(current = current.next) while current and index > (i += 1)
# Return null if we've reached the end.
current and current.data
@@ -43,16 +43,16 @@ class LinkedList
# Check for out-of-bounds values.
return null if index < 0
current = @_head or null
current = this._head or null
i = -1
# Special case: removing the first item.
if index is 0
@_head = current.next
this._head = current.next
else
# Find the right location.
[previous, current] = [current, current.next] while index > ++i
([previous, current] = [current, current.next]) while index > (i += 1)
# Skip over the item to remove.
previous.next = current.next
@@ -63,7 +63,7 @@ class LinkedList
# Calculate the number of items in the list.
size: ->
current = @_head
current = this._head
count = 0
while current
@@ -76,7 +76,7 @@ class LinkedList
# Convert the list into an array.
toArray: ->
result = []
current = @_head
current = this._head
while current
result.push current.data
@@ -86,7 +86,7 @@ class LinkedList
# The string representation of the linked list.
toString: -> @toArray().toString()
toString: -> this.toArray().toString()
# Tests.

View File

@@ -7,13 +7,13 @@ is_valid_identifier = (identifier) ->
sum = 0
alt = false
for c in identifier by -1
for i in [identifier.length - 1..0] by -1
# Get the next digit.
num = parseInt c, 10
num = parseInt identifier.charAt(i), 10
# If it's not a valid number, abort.
return false if isNaN num
return false if isNaN(num)
# If it's an alternate number...
if alt

View File

@@ -3,12 +3,13 @@ merge_sort = (list) ->
return list if list.length is 1
result = []
pivot = Math.floor list.length / 2
left = merge_sort list.slice 0, pivot
right = merge_sort list.slice pivot
result = while left.length and right.length
if left[0] < right[0] then left.shift() else right.shift()
while left.length and right.length
result.push(if left[0] < right[0] then left.shift() else right.shift())
result.concat(left).concat(right)

View File

@@ -1,11 +1,8 @@
# Examples from the Poignant Guide.
# These are examples of syntax differences between CoffeeScript and Ruby,
# they won't run.
# ['toast', 'cheese', 'wine'].each { |food| print food.capitalize }
print food.capitalize() for food in ['toast', 'wine', 'cheese']
['toast', 'wine', 'cheese'].each (food) -> print food.capitalize()
@@ -17,10 +14,10 @@ print food.capitalize() for food in ['toast', 'wine', 'cheese']
# end
LotteryTicket =
get_picks: -> @picks
set_picks: (@picks) ->
get_purchased: -> @purchase
set_purchased: (@purchased) ->
get_picks: -> @picks
set_picks: (@picks) ->
get_purchased: -> @purchase
set_purchased: (@purchased) ->
@@ -45,10 +42,13 @@ LotteryDraw =
play: ->
result = LotteryTicket.new_random()
winners = {}
for buyer, ticketList of @tickets
for ticket in ticketList when (score = ticket.score result) isnt 0
(winners[buyer] or= []).push [ticket, score]
@tickets = {}
this.tickets.each (buyer, ticket_list) ->
ticket_list.each (ticket) ->
score = ticket.score result
return if score is 0
winners[buyer] or= []
winners[buyer].push [ticket, score]
this.tickets = {}
winners
@@ -64,7 +64,7 @@ LotteryDraw =
WishScanner =
scan_for_a_wish: ->
wish = @read().detect (thought) -> thought.indexOf('wish: ') is 0
wish = this.read().detect (thought) -> thought.index('wish: ') is 0
wish.replace 'wish: ', ''
@@ -109,28 +109,28 @@ Creature =
# This method applies a hit taken during a fight.
hit: (damage) ->
p_up = Math.rand @charisma
p_up = Math.rand this.charisma
if p_up % 9 is 7
@life += p_up / 4
console.log "[#{@name} magick powers up #{p_up}!]"
@life -= damage
if @life <= 0 then console.log "[#{@name} has died.]"
this.life += p_up / 4
console.log "[" + this.name + " magick powers up " + p_up + "!]"
this.life -= damage
if this.life <= 0 then console.log "[" + this.name + " has died.]"
# This method takes one turn in a fight.
fight: (enemy, weapon) ->
return console.log "[#{@name} is too dead to fight!]" if @life <= 0
if this.life <= 0 then return console.log "[" + this.name + "is too dead to fight!]"
# Attack the opponent.
your_hit = Math.rand @strength + weapon
console.log "[You hit with #{your_hit}points of damage!]"
your_hit = Math.rand this.strength + weapon
console.log "[You hit with " + your_hit + "points of damage!]"
enemy.hit your_hit
# Retaliation.
console.log enemy
if enemy.life > 0
enemy_hit = Math.rand enemy.strength + enemy.weapon
console.log "[Your enemy hit with #{enemy_hit}points of damage!]"
@hit enemy_hit
console.log "[Your enemy hit with " + enemy_hit + "points of damage!]"
this.hit enemy_hit
@@ -156,7 +156,7 @@ code_words.each (real, code) -> idea.replace(real, code)
# Save the jibberish to a new file
print "File encoded. Please enter a name for this idea: "
idea_name = gets().strip()
File.open "idea-#{idea_name}.txt", 'w', (file) -> file.write idea
File.open "idea-" + idea_name + '.txt', 'w', (file) -> file.write idea
@@ -174,8 +174,8 @@ File.open "idea-#{idea_name}.txt", 'w', (file) -> file.write idea
wipe_mutterings_from = (sentence) ->
throw new Error "cannot wipe mutterings" unless sentence.indexOf
while '(' in sentence
open = sentence.indexOf('(')
close = sentence.indexOf(')')
sentence = "#{sentence[0...open]}#{sentence[close + 1..]}"
while sentence.indexOf('(') >= 0
open = sentence.indexOf('(') - 1
close = sentence.indexOf(')') + 1
sentence = sentence.slice(0, open) + sentence.slice(close, sentence.length)
sentence

View File

@@ -45,7 +45,7 @@ foods[2]
# (key, ' is a ', val) join print.
for key, val of {dog: 'canine', cat: 'feline', fox: 'vulpine'}
print "#{key} is a #{val}"
print key + ' is a ' + val
# Person = class: /name, /age, /sex.
@@ -54,7 +54,7 @@ for key, val of {dog: 'canine', cat: 'feline', fox: 'vulpine'}
class Person
print: ->
print "My name is #{@name}."
print 'My name is ' + @name + '.'
# p = Person ()
@@ -74,7 +74,7 @@ class Policeman extends Person
(@rank) ->
print: ->
print "My name is #{@name} and I'm a #{@rank}."
print 'My name is ' + @name + " and I'm a " + @rank + '.'
print new Policeman 'Constable'
@@ -180,7 +180,7 @@ if 3.gender?
# session = url query ? at ('session').
HomePage::get = (url) ->
session = url.query?.session
session = url.query.session if url.query?
# BTree = class: /left, /right.

View File

@@ -7,6 +7,6 @@ server = http.createServer (req, res) ->
res.write 'Hello, World!'
res.end()
server.listen PORT = 3000
server.listen 3000
console.log "Server running at http://localhost:#{PORT}/"
console.log "Server running at http://localhost:3000/"

File diff suppressed because one or more lines are too long

44
extras/jsl.conf Normal file
View File

@@ -0,0 +1,44 @@
# JavaScriptLint configuration file for CoffeeScript.
+no_return_value # function {0} does not always return a value
+duplicate_formal # duplicate formal argument {0}
-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
+var_hides_arg # variable {0} hides argument
+redeclared_var # redeclaration of {0} {1}
-anon_no_return_value # anonymous function does not always return a value
+missing_semicolon # missing semicolon
+meaningless_block # meaningless block; curly braces have no impact
-comma_separated_stmts # multiple statements separated by commas (use semicolons?)
+unreachable_code # unreachable code
+missing_break # missing break statement
-missing_break_for_last_case # missing break statement for last case in switch
-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
-useless_void # use of the void type may be unnecessary (void is always undefined)
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
+use_of_label # use of label
-block_without_braces # block statement without curly braces
+leading_decimal_point # leading decimal point may indicate a number or an object member
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
+octal_number # leading zeros make an octal number
+nested_comment # nested comment
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
+empty_statement # empty statement or extra semicolon
-missing_option_explicit # the "option explicit" control comment is missing
+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
+dup_option_explicit # duplicate "option explicit" control comment
+useless_assign # useless assignment
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
-missing_default_case # missing default case in switch statement
+duplicate_case_in_switch # duplicate case in switch statements
+default_not_at_end # the default case is not at the end of the switch statement
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
+useless_comparison # useless comparison; comparing identical expressions
+with_statement # with statement hides undeclared variables; use temporary variable instead
+trailing_comma_in_array # extra comma is not recommended in array initializers
+assign_to_function_call # assignment to a function call
+parseint_missing_radix # parseInt missing radix parameter
+lambda_assign_requires_semicolon

1396
index.html

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,21 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var CoffeeScript, compile, runScripts,
var CoffeeScript, runScripts,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
CoffeeScript = require('./coffee-script');
CoffeeScript.require = require;
compile = CoffeeScript.compile;
CoffeeScript["eval"] = function(code, options) {
var _ref;
if (options == null) {
options = {};
}
if (options.bare == null) {
if ((_ref = options.bare) == null) {
options.bare = true;
}
return eval(compile(code, options));
return eval(CoffeeScript.compile(code, options));
};
CoffeeScript.run = function(code, options) {
@@ -24,54 +23,33 @@
options = {};
}
options.bare = true;
options.shiftLine = true;
return Function(compile(code, options))();
return Function(CoffeeScript.compile(code, options))();
};
if (typeof window === "undefined" || window === null) {
return;
}
if ((typeof btoa !== "undefined" && btoa !== null) && (typeof JSON !== "undefined" && JSON !== null) && (typeof unescape !== "undefined" && unescape !== null) && (typeof encodeURIComponent !== "undefined" && encodeURIComponent !== null)) {
compile = function(code, options) {
var js, v3SourceMap, _ref;
if (options == null) {
options = {};
}
options.sourceMap = true;
options.inline = true;
_ref = CoffeeScript.compile(code, options), js = _ref.js, v3SourceMap = _ref.v3SourceMap;
return "" + js + "\n//# sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//# sourceURL=coffeescript";
};
}
CoffeeScript.load = function(url, callback, options, hold) {
CoffeeScript.load = function(url, callback, options) {
var xhr;
if (options == null) {
options = {};
}
if (hold == null) {
hold = false;
}
options.sourceFiles = [url];
xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP') : new window.XMLHttpRequest();
xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
xhr.open('GET', url, true);
if ('overrideMimeType' in xhr) {
xhr.overrideMimeType('text/plain');
}
xhr.onreadystatechange = function() {
var param, _ref;
var _ref;
if (xhr.readyState === 4) {
if ((_ref = xhr.status) === 0 || _ref === 200) {
param = [xhr.responseText, options];
if (!hold) {
CoffeeScript.run.apply(CoffeeScript, param);
}
CoffeeScript.run(xhr.responseText, options);
} else {
throw new Error("Could not load " + url);
}
if (callback) {
return callback(param);
return callback();
}
}
};
@@ -79,8 +57,8 @@
};
runScripts = function() {
var coffees, coffeetypes, execute, i, index, s, script, scripts, _fn, _i, _len;
scripts = window.document.getElementsByTagName('script');
var coffees, coffeetypes, execute, index, length, s, scripts;
scripts = document.getElementsByTagName('script');
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript'];
coffees = (function() {
var _i, _len, _ref, _results;
@@ -94,41 +72,30 @@
return _results;
})();
index = 0;
execute = function() {
var param;
param = coffees[index];
if (param instanceof Array) {
CoffeeScript.run.apply(CoffeeScript, param);
index++;
return execute();
}
};
_fn = function(script, i) {
var options;
options = {
literate: script.type === coffeetypes[1]
};
if (script.src) {
return CoffeeScript.load(script.src, function(param) {
coffees[i] = param;
length = coffees.length;
(execute = function() {
var mediatype, options, script;
script = coffees[index++];
mediatype = script != null ? script.type : void 0;
if (__indexOf.call(coffeetypes, mediatype) >= 0) {
options = {
literate: mediatype === 'text/literate-coffeescript'
};
if (script.src) {
return CoffeeScript.load(script.src, execute, options);
} else {
CoffeeScript.run(script.innerHTML, options);
return execute();
}, options, true);
} else {
options.sourceFiles = ['embedded'];
return coffees[i] = [script.innerHTML, options];
}
}
};
for (i = _i = 0, _len = coffees.length; _i < _len; i = ++_i) {
script = coffees[i];
_fn(script, i);
}
return execute();
})();
return null;
};
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', runScripts, false);
addEventListener('DOMContentLoaded', runScripts, false);
} else {
window.attachEvent('onload', runScripts);
attachEvent('onload', runScripts);
}
}).call(this);

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
var CoffeeScript, cakefileDirectory, existsSync, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
fs = require('fs');
@@ -12,6 +12,8 @@
CoffeeScript = require('./coffee-script');
existsSync = fs.existsSync || path.existsSync;
tasks = {};
options = {};
@@ -44,7 +46,7 @@
});
exports.run = function() {
var arg, args, e, _i, _len, _ref, _results;
var arg, args, _i, _len, _ref, _results;
global.__originalDirname = fs.realpathSync('.');
process.chdir(cakefileDirectory(__originalDirname));
args = process.argv.slice(2);
@@ -57,8 +59,7 @@
}
try {
options = oparse.parse(args);
} catch (_error) {
e = _error;
} catch (e) {
return fatalError("" + e);
}
_ref = options["arguments"];
@@ -99,7 +100,7 @@
cakefileDirectory = function(dir) {
var parent;
if (fs.existsSync(path.join(dir, 'Cakefile'))) {
if (existsSync(path.join(dir, 'Cakefile'))) {
return dir;
}
parent = path.normalize(path.join(dir, '..'));

View File

@@ -1,13 +1,10 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var Lexer, SourceMap, compile, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors,
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
var Lexer, compile, ext, fs, helpers, lexer, loadFile, parser, path, sourcemap, vm, _i, _len, _ref,
__hasProp = {}.hasOwnProperty;
fs = require('fs');
vm = require('vm');
path = require('path');
Lexer = require('./lexer').Lexer;
@@ -16,63 +13,73 @@
helpers = require('./helpers');
SourceMap = require('./sourcemap');
vm = require('vm');
exports.VERSION = '1.7.0';
sourcemap = require('./sourcemap');
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
loadFile = function(module, filename) {
var raw, stripped;
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
return module._compile(compile(stripped, {
filename: filename,
literate: helpers.isLiterate(filename)
}), filename);
};
if (require.extensions) {
_ref = ['.coffee', '.litcoffee', '.md', '.coffee.md'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ext = _ref[_i];
require.extensions[ext] = loadFile;
}
}
exports.VERSION = '1.6.1';
exports.helpers = helpers;
withPrettyErrors = function(fn) {
return function(code, options) {
var err;
if (options == null) {
options = {};
}
try {
return fn.call(this, code, options);
} catch (_error) {
err = _error;
throw helpers.updateSyntaxError(err, code, options.filename);
}
};
};
exports.compile = compile = withPrettyErrors(function(code, options) {
var answer, currentColumn, currentLine, extend, fragment, fragments, header, js, map, merge, newLines, _i, _len;
merge = helpers.merge, extend = helpers.extend;
options = extend({}, options);
if (options.sourceMap) {
map = new SourceMap;
exports.compile = compile = function(code, options) {
var answer, coffeeFile, currentColumn, currentLine, fragment, fragments, header, js, jsFile, merge, newLines, sourceMap, _j, _len1;
if (options == null) {
options = {};
}
fragments = parser.parse(lexer.tokenize(code, options)).compileToFragments(options);
currentLine = 0;
if (options.header) {
currentLine += 1;
}
if (options.shiftLine) {
currentLine += 1;
}
currentColumn = 0;
js = "";
for (_i = 0, _len = fragments.length; _i < _len; _i++) {
fragment = fragments[_i];
merge = exports.helpers.merge;
try {
if (options.sourceMap) {
if (fragment.locationData) {
map.add([fragment.locationData.first_line, fragment.locationData.first_column], [currentLine, currentColumn], {
noReplace: true
});
}
newLines = helpers.count(fragment.code, "\n");
currentLine += newLines;
if (newLines) {
currentColumn = fragment.code.length - (fragment.code.lastIndexOf("\n") + 1);
} else {
currentColumn += fragment.code.length;
}
coffeeFile = helpers.baseFileName(options.filename);
jsFile = helpers.baseFileName(options.filename, true) + ".js";
sourceMap = new sourcemap.SourceMap();
}
js += fragment.code;
fragments = (parser.parse(lexer.tokenize(code, options))).compileToFragments(options);
currentLine = 0;
if (options.header) {
currentLine += 1;
}
if (options.sourceMap) {
currentLine += 1;
}
currentColumn = 0;
js = "";
for (_j = 0, _len1 = fragments.length; _j < _len1; _j++) {
fragment = fragments[_j];
if (sourceMap) {
if (fragment.locationData) {
sourceMap.addMapping([fragment.locationData.first_line, fragment.locationData.first_column], [currentLine, currentColumn], {
noReplace: true
});
}
newLines = helpers.count(fragment.code, "\n");
currentLine += newLines;
currentColumn = fragment.code.length - (newLines ? fragment.code.lastIndexOf("\n") : 0);
}
js += fragment.code;
}
} catch (err) {
if (options.filename) {
err.message = "In " + options.filename + ", " + err.message;
}
throw err;
}
if (options.header) {
header = "Generated by CoffeeScript " + this.VERSION;
@@ -82,45 +89,46 @@
answer = {
js: js
};
answer.sourceMap = map;
answer.v3SourceMap = map.generate(options, code);
if (sourceMap) {
answer.sourceMap = sourceMap;
answer.v3SourceMap = sourcemap.generateV3SourceMap(sourceMap, coffeeFile, jsFile);
}
return answer;
} else {
return js;
}
});
};
exports.tokens = withPrettyErrors(function(code, options) {
exports.tokens = function(code, options) {
return lexer.tokenize(code, options);
});
};
exports.nodes = withPrettyErrors(function(source, options) {
exports.nodes = function(source, options) {
if (typeof source === 'string') {
return parser.parse(lexer.tokenize(source, options));
} else {
return parser.parse(source);
}
});
};
exports.run = function(code, options) {
var answer, dir, mainModule, _ref;
var mainModule;
if (options == null) {
options = {};
}
mainModule = require.main;
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
mainModule.moduleCache && (mainModule.moduleCache = {});
dir = options.fileName ? path.dirname(fs.realpathSync(options.filename)) : fs.realpathSync('.');
mainModule.paths = require('module')._nodeModulePaths(dir);
mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename)));
if (!helpers.isCoffee(mainModule.filename) || require.extensions) {
answer = compile(code, options);
code = (_ref = answer.js) != null ? _ref : answer;
return mainModule._compile(compile(code, options), mainModule.filename);
} else {
return mainModule._compile(code, mainModule.filename);
}
return mainModule._compile(code, mainModule.filename);
};
exports["eval"] = function(code, options) {
var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref, _ref1, _require;
var Module, Script, js, k, o, r, sandbox, v, _j, _len1, _module, _ref1, _ref2, _require;
if (options == null) {
options = {};
}
@@ -134,10 +142,10 @@
sandbox = options.sandbox;
} else {
sandbox = Script.createContext();
_ref = options.sandbox;
for (k in _ref) {
if (!__hasProp.call(_ref, k)) continue;
v = _ref[k];
_ref1 = options.sandbox;
for (k in _ref1) {
if (!__hasProp.call(_ref1, k)) continue;
v = _ref1[k];
sandbox[k] = v;
}
}
@@ -154,9 +162,9 @@
return Module._load(path, _module, true);
};
_module.filename = sandbox.__filename;
_ref1 = Object.getOwnPropertyNames(require);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
r = _ref1[_i];
_ref2 = Object.getOwnPropertyNames(require);
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
r = _ref2[_j];
if (r !== 'paths') {
_require[r] = require[r];
}
@@ -182,30 +190,6 @@
}
};
exports.register = function() {
return require('./register');
};
exports._compileFile = function(filename, sourceMap) {
var answer, err, raw, stripped;
if (sourceMap == null) {
sourceMap = false;
}
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
try {
answer = compile(stripped, {
filename: filename,
sourceMap: sourceMap,
literate: helpers.isLiterate(filename)
});
} catch (_error) {
err = _error;
throw helpers.updateSyntaxError(err, stripped, filename);
}
return answer;
};
lexer = new Lexer;
parser.lexer = {
@@ -214,7 +198,6 @@
token = this.tokens[this.pos++];
if (token) {
tag = token[0], this.yytext = token[1], this.yylloc = token[2];
this.errorToken = token.origin || token;
this.yylineno = this.yylloc.first_line;
} else {
tag = '';
@@ -232,104 +215,4 @@
parser.yy = require('./nodes');
parser.yy.parseError = function(message, _arg) {
var errorLoc, errorTag, errorText, errorToken, token, tokens, _ref;
token = _arg.token;
_ref = parser.lexer, errorToken = _ref.errorToken, tokens = _ref.tokens;
errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2];
errorText = errorToken === tokens[tokens.length - 1] ? 'end of input' : errorTag === 'INDENT' || errorTag === 'OUTDENT' ? 'indentation' : helpers.nameWhitespaceCharacter(errorText);
return helpers.throwSyntaxError("unexpected " + errorText, errorLoc);
};
formatSourcePosition = function(frame, getSourceMapping) {
var as, column, fileLocation, fileName, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName;
fileName = void 0;
fileLocation = '';
if (frame.isNative()) {
fileLocation = "native";
} else {
if (frame.isEval()) {
fileName = frame.getScriptNameOrSourceURL();
if (!fileName) {
fileLocation = "" + (frame.getEvalOrigin()) + ", ";
}
} else {
fileName = frame.getFileName();
}
fileName || (fileName = "<anonymous>");
line = frame.getLineNumber();
column = frame.getColumnNumber();
source = getSourceMapping(fileName, line, column);
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] : "" + fileName + ":" + line + ":" + column;
}
functionName = frame.getFunctionName();
isConstructor = frame.isConstructor();
isMethodCall = !(frame.isToplevel() || isConstructor);
if (isMethodCall) {
methodName = frame.getMethodName();
typeName = frame.getTypeName();
if (functionName) {
tp = as = '';
if (typeName && functionName.indexOf(typeName)) {
tp = "" + typeName + ".";
}
if (methodName && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) {
as = " [as " + methodName + "]";
}
return "" + tp + functionName + as + " (" + fileLocation + ")";
} else {
return "" + typeName + "." + (methodName || '<anonymous>') + " (" + fileLocation + ")";
}
} else if (isConstructor) {
return "new " + (functionName || '<anonymous>') + " (" + fileLocation + ")";
} else if (functionName) {
return "" + functionName + " (" + fileLocation + ")";
} else {
return fileLocation;
}
};
sourceMaps = {};
getSourceMap = function(filename) {
var answer, _ref;
if (sourceMaps[filename]) {
return sourceMaps[filename];
}
if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(exports.FILE_EXTENSIONS, _ref) < 0) {
return;
}
answer = exports._compileFile(filename, true);
return sourceMaps[filename] = answer.sourceMap;
};
Error.prepareStackTrace = function(err, stack) {
var frame, frames, getSourceMapping, _ref;
getSourceMapping = function(filename, line, column) {
var answer, sourceMap;
sourceMap = getSourceMap(filename);
if (sourceMap) {
answer = sourceMap.sourceLocation([line - 1, column - 1]);
}
if (answer) {
return [answer[0] + 1, answer[1] + 1];
} else {
return null;
}
};
frames = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = stack.length; _i < _len; _i++) {
frame = stack[_i];
if (frame.getFunction() === exports.run) {
break;
}
_results.push(" at " + (formatSourcePosition(frame, getSourceMapping)));
}
return _results;
})();
return "" + err.name + ": " + ((_ref = err.message) != null ? _ref : '') + "\n" + (frames.join('\n')) + "\n";
};
}).call(this);

View File

@@ -1,7 +1,6 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, lint, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref;
fs = require('fs');
@@ -13,13 +12,11 @@
CoffeeScript = require('./coffee-script');
mkdirp = require('mkdirp');
_ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
EventEmitter = require('events').EventEmitter;
useWinPathSep = path.sep === '\\';
exists = fs.exists || path.exists;
helpers.extend(CoffeeScript, new EventEmitter);
@@ -37,7 +34,7 @@
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
opts = {};
@@ -47,16 +44,13 @@
notSources = {};
watchedDirs = {};
watchers = {};
optionParser = null;
exports.run = function() {
var literals, replCliOpts, source, _i, _len, _ref1, _results;
var literals, source, _i, _len, _results;
parseOptions();
replCliOpts = {
useGlobal: true
};
if (opts.nodejs) {
return forkNode();
}
@@ -67,130 +61,96 @@
return version();
}
if (opts.interactive) {
return require('./repl').start(replCliOpts);
return require('./repl').start();
}
if (opts.watch && !fs.watch) {
return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
}
if (opts.stdio) {
return compileStdio();
}
if (opts["eval"]) {
return compileScript(null, opts["arguments"][0]);
return compileScript(null, sources[0]);
}
if (!opts["arguments"].length) {
return require('./repl').start(replCliOpts);
if (!sources.length) {
return require('./repl').start();
}
literals = opts.run ? opts["arguments"].splice(1) : [];
literals = opts.run ? sources.splice(1) : [];
process.argv = process.argv.slice(0, 2).concat(literals);
process.argv[0] = 'coffee';
if (opts.output) {
opts.output = path.resolve(opts.output);
}
if (opts.join) {
opts.join = path.resolve(opts.join);
}
_ref1 = opts["arguments"];
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
source = _ref1[_i];
source = path.resolve(source);
_results.push(compilePath(source, true, source));
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
_results.push(compilePath(source, true, path.normalize(source)));
}
return _results;
};
compilePath = function(source, topLevel, base) {
var code, err, file, files, stats, _i, _len, _results;
if (__indexOf.call(sources, source) >= 0 || watchedDirs[source] || !topLevel && (notSources[source] || hidden(source))) {
return;
}
try {
stats = fs.statSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
return fs.stat(source, function(err, stats) {
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
console.error("File not found: " + source);
process.exit(1);
}
throw err;
}
if (stats.isDirectory()) {
if (path.basename(source) === 'node_modules') {
if (stats.isDirectory() && path.dirname(source) !== 'node_modules') {
if (opts.watch) {
watchDir(source, base);
}
return fs.readdir(source, function(err, files) {
var file, index, _ref1, _ref2;
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
return;
}
index = sources.indexOf(source);
files = files.filter(function(file) {
return !hidden(file);
});
[].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(path.join(source, file));
}
return _results;
})())), _ref1;
[].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
return null;
}))), _ref2;
return files.forEach(function(file) {
return compilePath(path.join(source, file), false, base);
});
});
} else if (topLevel || helpers.isCoffee(source)) {
if (opts.watch) {
watch(source, base);
}
return fs.readFile(source, function(err, code) {
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
return;
}
return compileScript(source, code.toString(), base);
});
} else {
notSources[source] = true;
return;
return removeSource(source, base);
}
if (opts.run) {
compilePath(findDirectoryIndex(source), topLevel, base);
return;
}
if (opts.watch) {
watchDir(source, base);
}
try {
files = fs.readdirSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
return;
} else {
throw err;
}
}
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(compilePath(path.join(source, file), false, base));
}
return _results;
} else if (topLevel || helpers.isCoffee(source)) {
sources.push(source);
sourceCode.push(null);
delete notSources[source];
if (opts.watch) {
watch(source, base);
}
try {
code = fs.readFileSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
return;
} else {
throw err;
}
}
return compileScript(source, code.toString(), base);
} else {
return notSources[source] = true;
}
};
findDirectoryIndex = function(source) {
var err, ext, index, _i, _len, _ref1;
_ref1 = CoffeeScript.FILE_EXTENSIONS;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
ext = _ref1[_i];
index = path.join(source, "index" + ext);
try {
if ((fs.statSync(index)).isFile()) {
return index;
}
} catch (_error) {
err = _error;
if (err.code !== 'ENOENT') {
throw err;
}
}
}
console.error("Missing index.coffee or index.litcoffee in " + source);
return process.exit(1);
});
};
compileScript = function(file, input, base) {
var compiled, err, message, o, options, t, task;
if (base == null) {
base = null;
}
var compiled, o, options, t, task;
o = opts;
options = compileOptions(file, base);
options = compileOptions(file);
try {
t = task = {
file: file,
@@ -203,12 +163,8 @@
} else if (o.nodes) {
return printLine(CoffeeScript.nodes(t.input, t.options).toString().trim());
} else if (o.run) {
CoffeeScript.register();
return CoffeeScript.run(t.input, t.options);
} else if (o.join && t.file !== o.join) {
if (helpers.isLiterate(file)) {
t.input = helpers.invertLiterate(t.input);
}
sourceCode[sources.indexOf(t.file)] = t.input;
return compileJoin();
} else {
@@ -222,22 +178,21 @@
if (o.print) {
return printLine(t.output.trim());
} else if (o.compile || o.map) {
return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap);
return writeJs(base, t.file, t.output, t.sourceMap);
} else if (o.lint) {
return lint(t.file, t.output);
}
}
} catch (_error) {
err = _error;
} catch (err) {
CoffeeScript.emit('failure', err, task);
if (CoffeeScript.listeners('failure').length) {
return;
}
message = err.stack || ("" + err);
if (o.watch) {
return printLine(message + '\x07');
} else {
printWarn(message);
return process.exit(1);
return printLine(err.message + '\x07');
}
printWarn(err instanceof Error && err.stack || ("ERROR: " + err));
return process.exit(1);
}
};
@@ -272,23 +227,23 @@
};
watch = function(source, base) {
var compile, compileTimeout, err, prevStats, rewatch, startWatcher, watchErr, watcher;
watcher = null;
var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
prevStats = null;
compileTimeout = null;
watchErr = function(err) {
if (err.code !== 'ENOENT') {
throw err;
}
if (__indexOf.call(sources, source) < 0) {
return;
}
try {
rewatch();
return compile();
} catch (_error) {
removeSource(source, base);
return compileJoin();
watchErr = function(e) {
if (e.code === 'ENOENT') {
if (sources.indexOf(source) === -1) {
return;
}
try {
rewatch();
return compile();
} catch (e) {
removeSource(source, base, true);
return compileJoin();
}
} else {
throw e;
}
};
compile = function() {
@@ -312,138 +267,126 @@
});
});
};
startWatcher = function() {
return watcher = fs.watch(source).on('change', compile).on('error', function(err) {
if (err.code !== 'EPERM') {
throw err;
}
return removeSource(source, base);
});
};
rewatch = function() {
try {
watcher = fs.watch(source, compile);
} catch (e) {
watchErr(e);
}
return rewatch = function() {
if (watcher != null) {
watcher.close();
}
return startWatcher();
return watcher = fs.watch(source, compile);
};
try {
return startWatcher();
} catch (_error) {
err = _error;
return watchErr(err);
}
};
watchDir = function(source, base) {
var err, readdirTimeout, startWatcher, stopWatcher, watcher;
watcher = null;
var readdirTimeout, watcher;
readdirTimeout = null;
startWatcher = function() {
return watcher = fs.watch(source).on('error', function(err) {
if (err.code !== 'EPERM') {
throw err;
}
return stopWatcher();
}).on('change', function() {
try {
return watcher = fs.watch(source, function() {
clearTimeout(readdirTimeout);
return readdirTimeout = wait(25, function() {
var err, file, files, _i, _len, _results;
try {
files = fs.readdirSync(source);
} catch (_error) {
err = _error;
if (err.code !== 'ENOENT') {
throw err;
return fs.readdir(source, function(err, files) {
var file, _i, _len, _results;
if (err) {
if (err.code !== 'ENOENT') {
throw err;
}
watcher.close();
return unwatchDir(source, base);
}
return stopWatcher();
}
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(compilePath(path.join(source, file), false, base));
}
return _results;
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
if (!(!hidden(file) && !notSources[file])) {
continue;
}
file = path.join(source, file);
if (sources.some(function(s) {
return s.indexOf(file) >= 0;
})) {
continue;
}
sources.push(file);
sourceCode.push(null);
_results.push(compilePath(file, false, base));
}
return _results;
});
});
});
};
stopWatcher = function() {
watcher.close();
return removeSourceDir(source, base);
};
watchedDirs[source] = true;
try {
return startWatcher();
} catch (_error) {
err = _error;
if (err.code !== 'ENOENT') {
throw err;
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
};
removeSourceDir = function(source, base) {
var file, sourcesChanged, _i, _len;
delete watchedDirs[source];
sourcesChanged = false;
for (_i = 0, _len = sources.length; _i < _len; _i++) {
file = sources[_i];
if (!(source === path.dirname(file))) {
continue;
unwatchDir = function(source, base) {
var file, prevSources, toRemove, _i, _len;
prevSources = sources.slice(0);
toRemove = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
file = sources[_i];
if (file.indexOf(source) >= 0) {
_results.push(file);
}
}
removeSource(file, base);
sourcesChanged = true;
return _results;
})();
for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
file = toRemove[_i];
removeSource(file, base, true);
}
if (sourcesChanged) {
return compileJoin();
if (!sources.some(function(s, i) {
return prevSources[i] !== s;
})) {
return;
}
return compileJoin();
};
removeSource = function(source, base) {
var index;
removeSource = function(source, base, removeJs) {
var index, jsPath;
index = sources.indexOf(source);
sources.splice(index, 1);
sourceCode.splice(index, 1);
if (!opts.join) {
silentUnlink(outputPath(source, base));
silentUnlink(outputPath(source, base, '.map'));
return timeLog("removed " + source);
}
};
silentUnlink = function(path) {
var err, _ref1;
try {
return fs.unlinkSync(path);
} catch (_error) {
err = _error;
if ((_ref1 = err.code) !== 'ENOENT' && _ref1 !== 'EPERM') {
throw err;
}
if (removeJs && !opts.join) {
jsPath = outputPath(source, base);
return exists(jsPath, function(itExists) {
if (itExists) {
return fs.unlink(jsPath, function(err) {
if (err && err.code !== 'ENOENT') {
throw err;
}
return timeLog("removed " + source);
});
}
});
}
};
outputPath = function(source, base, extension) {
var basename, dir, srcDir;
var baseDir, basename, dir, srcDir;
if (extension == null) {
extension = ".js";
}
basename = helpers.baseFileName(source, true, useWinPathSep);
basename = helpers.baseFileName(source, true);
srcDir = path.dirname(source);
if (!opts.output) {
dir = srcDir;
} else if (source === base) {
dir = opts.output;
} else {
dir = path.join(opts.output, path.relative(base, srcDir));
}
baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
return path.join(dir, basename + extension);
};
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap) {
var compile, jsDir, sourceMapPath;
writeJs = function(base, sourcePath, js, generatedSourceMap) {
var compile, jsDir, jsPath, sourceMapPath;
if (generatedSourceMap == null) {
generatedSourceMap = null;
}
jsPath = outputPath(sourcePath, base);
sourceMapPath = outputPath(sourcePath, base, ".map");
jsDir = path.dirname(jsPath);
compile = function() {
@@ -452,7 +395,7 @@
js = ' ';
}
if (generatedSourceMap) {
js = "" + js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n";
js = "//@ sourceMappingURL=" + (helpers.baseFileName(sourceMapPath)) + "\n" + js;
}
fs.writeFile(jsPath, js, function(err) {
if (err) {
@@ -470,11 +413,11 @@
});
}
};
return fs.exists(jsDir, function(itExists) {
return exists(jsDir, function(itExists) {
if (itExists) {
return compile();
} else {
return mkdirp(jsDir, compile);
return exec("mkdir -p " + jsDir, compile);
}
});
};
@@ -487,6 +430,19 @@
return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
};
lint = function(file, js) {
var conf, jsl, printIt;
printIt = function(buffer) {
return printLine(file + ':\t' + buffer.toString().trim());
};
conf = __dirname + '/../../extras/jsl.conf';
jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
jsl.stdout.on('data', printIt);
jsl.stderr.on('data', printIt);
jsl.stdin.write(js);
return jsl.stdin.end();
};
printTokens = function(tokens) {
var strings, tag, token, value;
strings = (function() {
@@ -504,58 +460,39 @@
};
parseOptions = function() {
var o;
var i, o, source, _i, _len;
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
o = opts = optionParser.parse(process.argv.slice(2));
o.compile || (o.compile = !!o.output);
o.run = !(o.compile || o.print || o.map);
return o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
o.run = !(o.compile || o.print || o.lint || o.map);
o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
sources = o["arguments"];
for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
source = sources[i];
sourceCode[i] = null;
}
};
compileOptions = function(filename, base) {
var answer, cwd, jsDir, jsPath;
answer = {
compileOptions = function(filename) {
return {
filename: filename,
literate: opts.literate || helpers.isLiterate(filename),
literate: helpers.isLiterate(filename),
bare: opts.bare,
header: opts.compile && !opts['no-header'],
header: opts.compile,
sourceMap: opts.map
};
if (filename) {
if (base) {
cwd = process.cwd();
jsPath = outputPath(filename, base);
jsDir = path.dirname(jsPath);
answer = helpers.merge(answer, {
jsPath: jsPath,
sourceRoot: path.relative(jsDir, cwd),
sourceFiles: [path.relative(cwd, filename)],
generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep)
});
} else {
answer = helpers.merge(answer, {
sourceRoot: "",
sourceFiles: [helpers.baseFileName(filename, false, useWinPathSep)],
generatedFile: helpers.baseFileName(filename, true, useWinPathSep) + ".js"
});
}
}
return answer;
};
forkNode = function() {
var args, nodeArgs, p;
var args, nodeArgs;
nodeArgs = opts.nodejs.split(/\s+/);
args = process.argv.slice(1);
args.splice(args.indexOf('--nodejs'), 2);
p = spawn(process.execPath, nodeArgs.concat(args), {
return spawn(process.execPath, nodeArgs.concat(args), {
cwd: process.cwd(),
env: process.env,
customFds: [0, 1, 2]
});
return p.on('exit', function(code) {
return process.exit(code);
});
};
usage = function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
@@ -32,7 +32,7 @@
Root: [
o('', function() {
return new Block;
}), o('Body')
}), o('Body'), o('Block TERMINATOR')
],
Body: [
o('Line', function() {
@@ -96,7 +96,8 @@
return new Value($1);
}), o('ObjAssignable : Expression', function() {
return new Assign(LOC(1)(new Value($1)), $3, 'object');
}), o('ObjAssignable : INDENT Expression OUTDENT', function() {
}), o('ObjAssignable :\
INDENT Expression OUTDENT', function() {
return new Assign(LOC(1)(new Value($1)), $4, 'object');
}), o('Comment')
],
@@ -148,8 +149,6 @@
return new Param($1, null, true);
}), o('ParamVar = Expression', function() {
return new Param($1, $3);
}), o('...', function() {
return new Expansion;
})
],
ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
@@ -329,11 +328,7 @@
return $1.concat($4);
})
],
Arg: [
o('Expression'), o('Splat'), o('...', function() {
return new Expansion;
})
],
Arg: [o('Expression'), o('Splat')],
SimpleArgs: [
o('Expression'), o('SimpleArgs , Expression', function() {
return [].concat($1, $3);
@@ -355,8 +350,6 @@
return [$2, $3];
}), o('CATCH Object Block', function() {
return [LOC(2)(new Value($2)), $3];
}), o('CATCH Block', function() {
return [null, $2];
})
],
Throw: [
@@ -519,9 +512,9 @@
type: $1
});
}), o('IfBlock ELSE IF Expression Block', function() {
return $1.addElse(LOC(3, 5)(new If($4, $5, {
return $1.addElse(new If($4, $5, {
type: $3
})));
}));
})
],
If: [
@@ -542,16 +535,14 @@
Operation: [
o('UNARY Expression', function() {
return new Op($1, $2);
}), o('UNARY_MATH Expression', function() {
return new Op($1, $2);
}), o('- Expression', (function() {
return new Op('-', $2);
}), {
prec: 'UNARY_MATH'
prec: 'UNARY'
}), o('+ Expression', (function() {
return new Op('+', $2);
}), {
prec: 'UNARY_MATH'
prec: 'UNARY'
}), o('-- SimpleAssignable', function() {
return new Op('--', $2);
}), o('++ SimpleAssignable', function() {
@@ -568,8 +559,6 @@
return new Op('-', $1, $3);
}), o('Expression MATH Expression', function() {
return new Op($2, $1, $3);
}), o('Expression ** Expression', function() {
return new Op($2, $1, $3);
}), o('Expression SHIFT Expression', function() {
return new Op($2, $1, $3);
}), o('Expression COMPARE Expression', function() {
@@ -582,11 +571,14 @@
} else {
return new Op($2, $1, $3);
}
}), o('SimpleAssignable COMPOUND_ASSIGN Expression', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN\
Expression', function() {
return new Assign($1, $3, $2);
}), o('SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN\
INDENT Expression OUTDENT', function() {
return new Assign($1, $4, $2);
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR Expression', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR\
Expression', function() {
return new Assign($1, $4, $2);
}), o('SimpleAssignable EXTENDS Expression', function() {
return new Extends($1, $3);
@@ -594,7 +586,7 @@
]
};
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['left', 'POST_IF']];
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
tokens = [];

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var buildLocationData, extend, flatten, last, repeat, syntaxErrorToString, _ref;
var buildLocationData, extend, flatten, _ref;
exports.starts = function(string, literal, start) {
return literal === string.substr(start, literal.length);
@@ -12,19 +12,6 @@
return literal === string.substr(string.length - len - (back || 0), len);
};
exports.repeat = repeat = function(str, n) {
var res;
res = '';
while (n > 0) {
if (n & 1) {
res += str;
}
n >>>= 1;
str += str;
}
return res;
};
exports.compact = function(array) {
var item, _i, _len, _results;
_results = [];
@@ -83,7 +70,7 @@
return val;
};
exports.last = last = function(array, back) {
exports.last = function(array, back) {
return array[array.length - (back || 0) - 1];
};
@@ -98,28 +85,6 @@
return false;
};
exports.invertLiterate = function(code) {
var line, lines, maybe_code;
maybe_code = true;
lines = (function() {
var _i, _len, _ref1, _results;
_ref1 = code.split('\n');
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
line = _ref1[_i];
if (maybe_code && /^([ ]{4}|[ ]{0,3}\t)/.test(line)) {
_results.push(line);
} else if (maybe_code = /^\s*$/.test(line)) {
_results.push(line);
} else {
_results.push('# ' + line);
}
}
return _results;
})();
return lines.join('\n');
};
buildLocationData = function(first, last) {
if (!last) {
return first;
@@ -156,23 +121,19 @@
}
};
exports.baseFileName = function(file, stripExt, useWinPathSep) {
var parts, pathSep;
exports.baseFileName = function(file, stripExt) {
var parts;
if (stripExt == null) {
stripExt = false;
}
if (useWinPathSep == null) {
useWinPathSep = false;
}
pathSep = useWinPathSep ? /\\|\// : /\//;
parts = file.split(pathSep);
parts = file.split('/');
file = parts[parts.length - 1];
if (!(stripExt && file.indexOf('.') >= 0)) {
if (!stripExt) {
return file;
}
parts = file.split('.');
parts.pop();
if (parts[parts.length - 1] === 'coffee' && parts.length > 1) {
if (parts[parts.length - 1] === 'coffee') {
parts.pop();
}
return parts.join('.');
@@ -186,67 +147,4 @@
return /\.(litcoffee|coffee\.md)$/.test(file);
};
exports.throwSyntaxError = function(message, location) {
var error;
error = new SyntaxError(message);
error.location = location;
error.toString = syntaxErrorToString;
error.stack = error.toString();
throw error;
};
exports.updateSyntaxError = function(error, code, filename) {
if (error.toString === syntaxErrorToString) {
error.code || (error.code = code);
error.filename || (error.filename = filename);
error.stack = error.toString();
}
return error;
};
syntaxErrorToString = function() {
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, start, _ref1, _ref2;
if (!(this.code && this.location)) {
return Error.prototype.toString.call(this);
}
_ref1 = this.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column;
if (last_line == null) {
last_line = first_line;
}
if (last_column == null) {
last_column = first_column;
}
filename = this.filename || '[stdin]';
codeLine = this.code.split('\n')[first_line];
start = first_column;
end = first_line === last_line ? last_column + 1 : codeLine.length;
marker = repeat(' ', start) + repeat('^', end - start);
if (typeof process !== "undefined" && process !== null) {
colorsEnabled = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS;
}
if ((_ref2 = this.colorful) != null ? _ref2 : colorsEnabled) {
colorize = function(str) {
return "\x1B[1;31m" + str + "\x1B[0m";
};
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
marker = colorize(marker);
}
return "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker;
};
exports.nameWhitespaceCharacter = function(string) {
switch (string) {
case ' ':
return 'space';
case '\n':
return 'newline';
case '\r':
return 'carriage return';
case '\t':
return 'tab';
default:
return string;
}
};
}).call(this);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var key, val, _ref;

View File

@@ -1,13 +1,14 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, UNARY_MATH, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LITERATE, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, locationDataToString, starts, _ref, _ref1,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, repeat = _ref1.repeat, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, locationDataToString = _ref1.locationDataToString;
exports.Lexer = Lexer = (function() {
function Lexer() {}
Lexer.prototype.tokenize = function(code, opts) {
@@ -17,7 +18,6 @@
}
this.literate = opts.literate;
this.indent = 0;
this.baseIndent = 0;
this.indebt = 0;
this.outdebt = 0;
this.indents = [];
@@ -43,6 +43,7 @@
};
Lexer.prototype.clean = function(code) {
var line, lines, match;
if (code.charCodeAt(0) === BOM) {
code = code.slice(1);
}
@@ -52,7 +53,21 @@
this.chunkLine--;
}
if (this.literate) {
code = invertLiterate(code);
lines = (function() {
var _i, _len, _ref2, _results;
_ref2 = code.split('\n');
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
line = _ref2[_i];
if (match = LITERATE.exec(line)) {
_results.push(line.slice(match[0].length));
} else {
_results.push('# ' + line);
}
}
return _results;
})();
code = lines.join('\n');
}
return code;
};
@@ -156,35 +171,40 @@
}
lexedLength = number.length;
if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
number = '0x' + parseInt(octalLiteral[1], 8).toString(16);
number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16);
}
if (binaryLiteral = /^0b([01]+)/.exec(number)) {
number = '0x' + parseInt(binaryLiteral[1], 2).toString(16);
number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
}
this.token('NUMBER', number, 0, lexedLength);
return lexedLength;
};
Lexer.prototype.stringToken = function() {
var octalEsc, quote, string, trimmed;
switch (quote = this.chunk.charAt(0)) {
var match, octalEsc, string;
switch (this.chunk.charAt(0)) {
case "'":
string = SIMPLESTR.exec(this.chunk)[0];
if (!(match = SIMPLESTR.exec(this.chunk))) {
return 0;
}
string = match[0];
this.token('STRING', string.replace(MULTILINER, '\\\n'), 0, string.length);
break;
case '"':
string = this.balancedString(this.chunk, '"');
}
if (!string) {
return 0;
}
trimmed = this.removeNewlines(string.slice(1, -1));
if (quote === '"' && 0 < string.indexOf('#{', 1)) {
this.interpolateString(trimmed, {
strOffset: 1,
lexedLength: string.length
});
} else {
this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length);
if (!(string = this.balancedString(this.chunk, '"'))) {
return 0;
}
if (0 < string.indexOf('#{', 1)) {
this.interpolateString(string.slice(1, -1), {
strOffset: 1,
lexedLength: string.length
});
} else {
this.token('STRING', this.escapeLines(string, 0, string.length));
}
break;
default:
return 0;
}
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
this.error("octal escape sequences " + string + " are not allowed");
@@ -224,7 +244,7 @@
if (here) {
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
herecomment: true,
indent: repeat(' ', this.indent)
indent: Array(this.indent + 1).join(' ')
}), 0, comment.length);
}
return comment.length;
@@ -244,7 +264,8 @@
if (this.chunk.charAt(0) !== '/') {
return 0;
}
if (length = this.heregexToken()) {
if (match = HEREGEX.exec(this.chunk)) {
length = this.heregexToken(match);
return length;
}
prev = last(this.tokens);
@@ -255,24 +276,21 @@
return 0;
}
_ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
if (regex === '//') {
return 0;
}
if (regex.slice(0, 2) === '/*') {
this.error('regular expressions cannot begin with `*`');
}
if (regex === '//') {
regex = '/(?:)/';
}
this.token('REGEX', "" + regex + flags, 0, match.length);
return match.length;
};
Lexer.prototype.heregexToken = function() {
var body, flags, flagsOffset, heregex, match, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (!(match = HEREGEX.exec(this.chunk))) {
return 0;
}
Lexer.prototype.heregexToken = function(match) {
var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
heregex = match[0], body = match[1], flags = match[2];
if (0 > body.indexOf('#{')) {
re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true);
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
if (re.match(/^\*/)) {
this.error('regular expressions cannot begin with `*`');
}
@@ -291,7 +309,7 @@
if (tag === 'TOKENS') {
tokens.push.apply(tokens, value);
} else if (tag === 'NEOSTRING') {
if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
continue;
}
value = value.replace(/\\/g, '\\\\');
@@ -344,48 +362,37 @@
this.suppressNewlines();
return indent.length;
}
if (!this.tokens.length) {
this.baseIndent = this.indent = size;
return indent.length;
}
diff = size - this.indent + this.outdebt;
this.token('INDENT', diff, indent.length - size, size);
this.token('INDENT', diff, 0, indent.length);
this.indents.push(diff);
this.ends.push('OUTDENT');
this.outdebt = this.indebt = 0;
this.indent = size;
} else if (size < this.baseIndent) {
this.error('missing indentation', indent.length);
} else {
this.indebt = 0;
this.outdentToken(this.indent - size, noNewlines, indent.length);
}
this.indent = size;
return indent.length;
};
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
var decreasedIndent, dent, lastIndent, _ref2;
decreasedIndent = this.indent - moveOut;
var dent, len;
while (moveOut > 0) {
lastIndent = this.indents[this.indents.length - 1];
if (!lastIndent) {
len = this.indents.length - 1;
if (this.indents[len] === void 0) {
moveOut = 0;
} else if (lastIndent === this.outdebt) {
} else if (this.indents[len] === this.outdebt) {
moveOut -= this.outdebt;
this.outdebt = 0;
} else if (lastIndent < this.outdebt) {
this.outdebt -= lastIndent;
moveOut -= lastIndent;
} else if (this.indents[len] < this.outdebt) {
this.outdebt -= this.indents[len];
moveOut -= this.indents[len];
} else {
dent = this.indents.pop() + this.outdebt;
if (outdentLength && (_ref2 = this.chunk[outdentLength], __indexOf.call(INDENTABLE_CLOSERS, _ref2) >= 0)) {
decreasedIndent -= dent - moveOut;
moveOut = dent;
}
moveOut -= dent;
this.outdebt = 0;
this.pair('OUTDENT');
this.token('OUTDENT', moveOut, 0, outdentLength);
moveOut -= dent;
this.token('OUTDENT', dent, 0, outdentLength);
}
}
if (dent) {
@@ -397,7 +404,6 @@
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
this.token('TERMINATOR', '\n', outdentLength, 0);
}
this.indent = decreasedIndent;
return this;
};
@@ -467,8 +473,6 @@
tag = 'COMPOUND_ASSIGN';
} else if (__indexOf.call(UNARY, value) >= 0) {
tag = 'UNARY';
} else if (__indexOf.call(UNARY_MATH, value) >= 0) {
tag = 'UNARY_MATH';
} else if (__indexOf.call(SHIFT, value) >= 0) {
tag = 'SHIFT';
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
@@ -523,6 +527,9 @@
if (indent) {
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
}
if (this.literate) {
doc = doc.replace(/\n# \n/g, '\n\n');
}
if (!herecomment) {
doc = doc.replace(/^\n/, '');
}
@@ -598,14 +605,18 @@
};
Lexer.prototype.interpolateString = function(str, options) {
var column, errorToken, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
offsetInChunk || (offsetInChunk = 0);
strOffset || (strOffset = 0);
lexedLength || (lexedLength = str.length);
offsetInChunk = offsetInChunk || 0;
strOffset = strOffset || 0;
lexedLength = lexedLength || str.length;
if (heredoc && str.length > 0 && str[0] === '\n') {
str = str.slice(1);
strOffset++;
}
tokens = [];
pi = 0;
i = -1;
@@ -620,9 +631,6 @@
if (pi < i) {
tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
}
if (!errorToken) {
errorToken = this.makeToken('', 'string interpolation', offsetInChunk + i + 1, 2);
}
inner = expr.slice(1, -1);
if (inner.length) {
_ref2 = this.getLineAndColumnFromChunk(strOffset + i + 1), line = _ref2[0], column = _ref2[1];
@@ -659,7 +667,7 @@
tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
}
if (interpolated = tokens.length > 1) {
this.token('(', '(', offsetInChunk, 0, errorToken);
this.token('(', '(', offsetInChunk, 0);
}
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
token = tokens[i];
@@ -687,20 +695,19 @@
}
}
if (interpolated) {
rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0);
rparen.stringEnd = true;
this.tokens.push(rparen);
this.token(')', ')', offsetInChunk + lexedLength, 0);
}
return tokens;
};
Lexer.prototype.pair = function(tag) {
var wanted;
var size, wanted;
if (tag !== (wanted = last(this.ends))) {
if ('OUTDENT' !== wanted) {
this.error("unmatched " + tag);
}
this.outdentToken(last(this.indents), true);
this.indent -= size = last(this.indents);
this.outdentToken(size, true);
return this.pair(tag);
}
return this.ends.pop();
@@ -720,7 +727,7 @@
column = this.chunkColumn;
if (lineCount > 0) {
lines = string.split('\n');
column = last(lines).length;
column = (last(lines)).length;
} else {
column += string.length;
}
@@ -738,17 +745,14 @@
locationData = {};
_ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = _ref2[0], locationData.first_column = _ref2[1];
lastCharacter = Math.max(0, length - 1);
_ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1];
_ref3 = this.getLineAndColumnFromChunk(offsetInChunk + (length - 1)), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1];
token = [tag, value, locationData];
return token;
};
Lexer.prototype.token = function(tag, value, offsetInChunk, length, origin) {
Lexer.prototype.token = function(tag, value, offsetInChunk, length) {
var token;
token = this.makeToken(tag, value, offsetInChunk, length);
if (origin) {
token.origin = origin;
}
this.tokens.push(token);
return token;
};
@@ -765,34 +769,19 @@
Lexer.prototype.unfinished = function() {
var _ref2;
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
};
Lexer.prototype.removeNewlines = function(str) {
return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1');
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
};
Lexer.prototype.escapeLines = function(str, heredoc) {
str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
if (character === '\n') {
return '';
} else {
return escaped;
}
});
if (heredoc) {
return str.replace(MULTILINER, '\\n');
} else {
return str.replace(/\s*\n\s*/g, ' ');
}
return str.replace(MULTILINER, heredoc ? '\\n' : '');
};
Lexer.prototype.makeString = function(body, quote, heredoc) {
if (!body) {
return quote + quote;
}
body = body.replace(RegExp("\\\\(" + quote + "|\\\\)", "g"), function(match, contents) {
if (contents === quote) {
body = body.replace(/\\([\s\S])/g, function(match, contents) {
if (contents === '\n' || contents === quote) {
return contents;
} else {
return match;
@@ -802,16 +791,8 @@
return quote + this.escapeLines(body, heredoc) + quote;
};
Lexer.prototype.error = function(message, offset) {
var first_column, first_line, _ref2;
if (offset == null) {
offset = 0;
}
_ref2 = this.getLineAndColumnFromChunk(offset), first_line = _ref2[0], first_column = _ref2[1];
return throwSyntaxError(message, {
first_line: first_line,
first_column: first_column
});
Lexer.prototype.error = function(message) {
throw SyntaxError("" + message + " on line " + (this.chunkLine + 1));
};
return Lexer;
@@ -861,27 +842,29 @@
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?(\.|::)|\.{2,3})/;
WHITESPACE = /^[^\n\S]+/;
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)$)|^(?:\s*#(?!##[^#]).*)+/;
LITERATE = /^([ ]{4}|\t)/;
CODE = /^[-=]>/;
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g;
HEREGEX_OMIT = /\s+(?:#.*)?/g;
MULTILINER = /\n/g;
@@ -893,11 +876,9 @@
TRAILING_SPACES = /\s+$/;
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%='];
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO'];
UNARY_MATH = ['!', '~'];
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
LOGIC = ['&&', '||', '&', '|', '^'];
@@ -905,15 +886,15 @@
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
MATH = ['*', '/', '%', '//', '%%'];
MATH = ['*', '/', '%'];
RELATION = ['IN', 'OF', 'INSTANCEOF'];
BOOL = ['TRUE', 'FALSE'];
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--'];
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']'];
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']');
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
@@ -921,6 +902,4 @@
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
INDENTABLE_CLOSERS = [')', '}', ']'];
}).call(this);

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
// Generated by CoffeeScript 1.7.0
// Generated by CoffeeScript 1.6.1
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat;
repeat = require('./helpers').repeat;
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
exports.OptionParser = OptionParser = (function() {
function OptionParser(rules, banner) {
this.banner = banner;
this.rules = buildRules(rules);
@@ -68,7 +67,7 @@
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
rule = _ref[_i];
spaces = 15 - rule.longFlag.length;
spaces = spaces > 0 ? repeat(' ', spaces) : '';
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
}

Some files were not shown because too many files have changed in this diff Show More