cake is a simplified version of Make
(Rake, Jake)
for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
and can call them from the command line, or invoke them from other tasks.
CoffeeScript can be used both on the server, as a command-line compiler based
on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
contains the main entry functions for tokenizing, parsing, and compiling
source CoffeeScript into JavaScript.
@@ -8,37 +8,79 @@ execute all scripts present in text/coffeescript tags.
path = require'path'{Lexer}=require'./lexer'{parser}=require'./parser'
-vm = require'vm'
Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
+
+
If options.sourceMap is specified, then options.filename must also be specified.
+
+
This returns a javascript string, unless options.sourceMap or options.returnObject are true,
+in which case this returns a `{js, v3SourceMap, sourceMap}
+object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for doing programatic
+lookups.
Parse a string of CoffeeScript code or an array of lexed tokens, and
return the AST. You can then compile it by calling .compile() on the root,
or traverse it by using .traverseChildren() with a callback.
Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
The CoffeeScript REPL uses this to run the input.
exports.eval = (code, options = {}) ->returnunlesscode = code.trim()Script = vm.Script
@@ -53,12 +95,12 @@ The CoffeeScript REPL uses this to run the input.
use the same hack node currently uses for their own REPL
_require.paths = _module.paths = Module._nodeModulePathsprocess.cwd()_require.resolve = (request) ->Module._resolveFilenamerequest,_moduleo = {}o[k]=vforownk,vofoptions
@@ -67,7 +109,7 @@ The CoffeeScript REPL uses this to run the input.
The real Lexer produces a generic stream of tokens. This object provides a
thin wrapper around it, compatible with the Jison API. We can then pass it
directly as a "Jison lexer".
The coffee utility. Handles command-line compilation of CoffeeScript
into various forms: saved into .js files or printed to stdout, piped to
JavaScript Lint or recompiled every time the source is
saved, printed as a token stream or as the syntax tree, or launch an
@@ -27,6 +27,7 @@ interactive REPL.
['-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']
@@ -40,8 +41,7 @@ interactive REPL.
Run coffee by parsing passed options and determining what action to take.
Many flags cause us to divert before compiling anything. Flags passed after
-- will be passed verbatim to your script as arguments in process.argv
exports.run = ->parseOptions()
@@ -59,18 +59,13 @@ Many flags cause us to divert before compiling anything. Flags passed after
process.argv[0]='coffee'forsourceinsourcescompilePathsource,yes,path.normalizesource
Compile a path, which could be a script or a directory. If a directory
-is passed, recursively compile all '.coffee' and '.litcoffee' extension source
-files in it and all subdirectories.
compilePath = (source, topLevel, base) ->
+is passed, recursively compile all '.coffee', '.litcoffee', and '.coffee.md'
+extension source files in it and all subdirectories.
compilePath = (source, topLevel, base) ->fs.statsource,(err, stats) ->throwerriferranderr.codeisnt'ENOENT'iferr?.codeis'ENOENT'
- iftopLevelandsourceandpath.extname(source)notincoffee_exts
- source = sources[sources.indexOf(source)]="#{source}.coffee"
- returncompilePathsource,topLevel,base
- iftopLevel
- console.error"File not found: #{source}"
- process.exit1
- return
+ console.error"File not found: #{source}"
+ process.exit1ifstats.isDirectory()andpath.dirname(source)isnt'node_modules'watchDirsource,baseifopts.watchfs.readdirsource,(err, files) ->
@@ -82,7 +77,7 @@ files in it and all subdirectories.
Write out a JavaScript source file with the compiled code. By default, files
are written out in cwd as .js files with the same name, but the output
-directory can be customized with --output.
writeJs = (source, js, base) ->
- jsPath = outputPathsource,base
+directory can be customized with --output.
+
+
If generatedSourceMap is provided, this will write a .map file into the
+same directory as the .js file.
Start up a new Node.js instance with the arguments in --nodejs passed to
+ {
+ filename
+ literate: helpers.isLiterate(filename)
+ bare: opts.bare
+ header: opts.compile
+ sourceMap: opts.maps
+ returnObject: yes
+ }
The CoffeeScript parser is generated by Jison
from this grammar file. Jison is a bottom-up parser generator, similar in
style to Bison, implemented in JavaScript.
It can recognize LALR(1), LR(0), SLR(1), and LR(1)
@@ -23,8 +23,7 @@ previous nonterminal.
Returns a function which adds location data to the first parameter passed
in, and returns the parameter. If the parameter is not a node, it will
just be passed through unaffected.
addLocationDataFn = (first, last) ->ifnotlast
@@ -103,10 +102,10 @@ through and printed to JavaScript.
o 'Assignable = INDENT Expression OUTDENT',->newAssign$1,$4]
An array or range comprehension has variables for the current element
and (optional) reference to the current index. Or, key, value, in the case
of object comprehensions.
ForVariables: [
@@ -345,27 +345,27 @@ are defined at the bottom of the page. It would be shorter if we could
combine most of these rules into a single generic Operand OpSymbol Operand
-type rule, but in order to make the precedence binding possible, separate
rules are necessary.
This file contains the common helper functions that we'd like to share among
the Lexer, Rewriter, and the Nodes. Merge objects, flatten
arrays, count characters, that sort of thing.
Peek at the end of a given string to see if it matches a sequence.
exports.ends = (string, literal, back) ->
@@ -51,6 +51,6 @@ updates that object's locationData. The object is returned either way.
"#{locationData.first_line+1}:#{locationData.first_column+1}-"+"#{locationData.last_line+1}:#{locationData.last_column+1}"else
- "No location data"
+ "No location data"
\ No newline at end of file
diff --git a/documentation/docs/index.html b/documentation/docs/index.html
index 3d18f629..e01224cc 100644
--- a/documentation/docs/index.html
+++ b/documentation/docs/index.html
@@ -1,3 +1,3 @@
- index.coffee
\ No newline at end of file
diff --git a/documentation/docs/lexer.html b/documentation/docs/lexer.html
index 557e68b1..aeccd12c 100644
--- a/documentation/docs/lexer.html
+++ b/documentation/docs/lexer.html
@@ -1,4 +1,4 @@
- lexer.coffee
The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
matches against the beginning of the source code. When a match is found,
a token is produced, we consume the match, and start again. Tokens are in the
form:
@@ -22,7 +22,6 @@ it has consumed.
Before returning the token stream, run it through the Rewriter
unless explicitly asked not to.
tokenize: (code, opts = {}) ->@literate = opts.literate# Are we lexing literate CoffeeScript?
- code = @cleancode# The stripped, cleaned original source code.@indent = 0# The current indentation level.@indebt = 0# The over-indentation at the current level.@outdebt = 0# The under-outdentation at the current level.
@@ -33,7 +32,8 @@ unless explicitly asked not to.
@chunkLine =
opts.lineor0# The start line for the current @chunk.@chunkColumn =
- opts.columnor0# The start column of the current @chunk.
At every position, run through this list of attempted matches,
+ opts.columnor0# The start column of the current @chunk.
+ code = @cleancode# The stripped, cleaned original source code.
At every position, run through this list of attempted matches,
short-circuiting if any of them succeed. Their order determines precedence:
@literalToken is the fallback catch-all.
i = 0while@chunk = code[i..]
@@ -58,8 +58,10 @@ short-circuiting if any of them succeed. Their order determines precedence:
returns, etc. If we're lexing literate CoffeeScript, strip external Markdown
by removing all lines that aren't indented by at least four spaces or a tab.
A source of ambiguity in our grammar used to be parameter lists in function
definitions versus argument lists in function calls. Walk backwards, tagging
@@ -505,21 +508,18 @@ correctly balanced throughout the course of the token stream.
Use length - 1 for the final offset - we're supplying the lastline and the lastcolumn,
-so if lastcolumn == firstcolumn, then we're looking at a character of length 1.
lastCharacter = iflength>0then(length-1)else0
+so if lastcolumn == firstcolumn, then we're looking at a character of length 1.
Add a token to the results.
offset is the offset into the current @chunk where the token starts.
length is the length of the token in the @chunk, after the offset. If
not specified, the length of value will be used.
@@ -527,11 +527,11 @@ not specified, the length of value will be used.
nodes.coffee contains all of the node classes for the syntax tree. Most
nodes are created as the result of actions in the grammar,
but some are created by other nodes as a method of code generation. To convert
-the syntax tree into a string of JavaScript code, call compile() on the root.
{Scope}=require'./scope'
+the syntax tree into a string of JavaScript code, call compile() on the root.
The various nodes defined below all compile to a collection of CodeFragment objects.
+A CodeFragments is a block of generated code, and the location in the source file where the code
+came from. CodeFragments can be assembled together into working code just by catting together
+all the CodeFragments' code snippets, in order.
The Base is the abstract base class for all nodes in the syntax tree.
Each subclass implements the compileNode method, which performs the
code generation for that node. To compile a node to JavaScript,
call compile on it, which wraps compileNode in some generic extra smarts,
@@ -14,12 +27,15 @@ to know when the generated code needs to be wrapped up in a closure.
An options hash is passed and cloned throughout, containing information about
the environment from higher in the tree (such as if a returned value is
being requested by the surrounding function), information about the current
-scope, and indentation level.
Common logic for determining whether to wrap this node in a closure before
compiling it, or to compile directly. We need to wrap if this node is a
statement, and it's not a pureStatement, and we're not at
the top level of a block (which would be unnecessary), and we haven't
already been asked to return the result (because statements know how to
-return results).
If the code generation wishes to use the result of a complex expression
in multiple places, ensure that the expression is only ever evaluated once,
-by assigning it to a temporary variable. Pass a level to precompile.
cache: (o, level, reused) ->
+by assigning it to a temporary variable. Pass a level to precompile.
+
+
If level is passed, then returns [val, ref], where val is the compiled value, and ref
+is the compiled reference. If level is not passed, this returns [val, ref] where
+the two values are raw nodes which have not been compiled.
Construct a node that returns the current node's result.
+ iflevelthen[sub.compileToFragments(o,level),[@makeCode(ref.value)]]else[sub,ref]
+
+ cacheToCodeFragments: (cacheValues) ->
+ [fragmentsToText(cacheValues[0]),fragmentsToText(cacheValues[1])]
Does this node, or any of its children, contain a node of a certain kind?
Recursively traverses down the children of the nodes, yielding to a block
and returning true when the block finds a match. contains does not cross
scope boundaries.
Passes each child to a function, breaking when the function returns false.
eachChild: (func) ->returnthisunless@childrenforattrin@childrenwhen@[attr]forchildinflatten[@[attr]]
@@ -80,12 +103,12 @@ This is what coffee --nodes prints out.
The block is the list of expressions that forms the body of an
+ child.updateLocationDataIfMissinglocationData
+
+ makeCode: (code) ->
+ newCodeFragmentthis,code
+
+ wrapInBraces: (fragments) ->
+ [].concat@makeCode('('),fragments,@makeCode(')')
fragmentsList is an array of arrays of fragments. Each array in fragmentsList will be
+concatonated together, with joinStr added in between each, to produce a final flat array
+of fragments.
The block is the list of expressions that forms the body of an
indented block of code -- the implementation of a function, a clause in an
if, switch, or try, and so on...
Compile all expressions within the Block body. If we need to
return the result, and it's an expression, simply return it. If it's a
statement, ask the statement to do so.
This is a nested block. We don't do anything special here like enclose
it in a new scope; we just compile the statements in this block along with
-our own
If we happen to be the top-level Block, wrap everything in
+ return@joinFragmentArrays(compiledNodes,'\n')
+ ifcompiledNodes.length
+ answer = @joinFragmentArrays(compiledNodes,', ')
+ else
+ answer = [@makeCode"void 0"]
+ ifcompiledNodes.length>1ando.level>=LEVEL_LISTthen@wrapInBracesanswerelseanswer
If we happen to be the top-level Block, wrap everything in
a safety closure, unless requested not to.
It would be better not to generate them in the first place, but for now,
clean up obvious double-parentheses.
Compile the expressions body for the contents of a function, with
+ fragments = @compileWithDeclarationso
+ returnfragmentsifo.bare
+ [].concatprelude,@makeCode("(function() {\n"),fragments,@makeCode("\n}).call(this);\n")
Wrap up the given nodes as a Block, unless it already happens
+ fragments.push@makeCode",\n#{@tab+TAB}"ifdeclars
+ fragments.push@makeCode(scope.assignedVariables().join",\n#{@tab+TAB}")
+ fragments.push@makeCode';\n'
+ fragments.concatpost
A reference has base part (this value) and name part.
We cache them separately for compiling complex expressions.
a()[b()] ?= c -> (_base = a())[_name = b()] ? _base[_name] = c
cacheReference: (o) ->name = last@propertiesif@properties.length<2andnot@base.isComplex()andnotname?.isComplex()return[this,this]# `a` `a.b`
- base = Value.wrap@base,@properties[...-1]
+ base = newValue@base,@properties[...-1]ifbase.isComplex()# `a().b`bref = newLiteralo.scope.freeVariable'base'
- base = Value.wrapnewParensnewAssignbref,base
+ base = newValuenewParensnewAssignbref,basereturn[base,bref]unlessname# `a()`ifname.isComplex()# `a[b()]`nref = newLiteralo.scope.freeVariable'name'name = newIndexnewAssignnref,name.indexnref = newIndexnref
- [base.add(name),Value.wrap(breforbase.base,[nreforname])]
We compile a value to JavaScript by compiling and joining each property.
Things get much more interesting if the chain of properties has soak
operators ?. interspersed. Then we have to take care not to accidentally
evaluate anything twice when building the soak chain.
If you call a function with a splat, it's converted into a JavaScript
+ if@isNewthenfragments.push@makeCode'new '
+ fragments.push(@variable.compileToFragments(o,LEVEL_ACCESS))...
+ fragments.push@makeCode"("
+ fragments.pushcompiledArgs...
+ fragments.push@makeCode")"
+ fragments
If you call a function with a splat, it's converted into a JavaScript
.apply() call to allow an array of arguments to be passed.
If it's a constructor, then things get real tricky. We have to inject an
-inner constructor in order to be able to pass the varargs.
compileSplat: (o, splatArgs) ->
- return"#{@superReferenceo}.apply(#{@superThis(o)}, #{splatArgs})"if@isSuper
+inner constructor in order to be able to pass the varargs.
+
+
splatArgs is an array of CodeFragments to put into the 'apply'.
compileSplat: (o, splatArgs) ->
+ if@isSuper
+ return[].concat@makeCode("#{@superReferenceo}.apply(#{@superThis(o)}, "),
+ splatArgs,@makeCode(")")
+
if@isNewidt = @tab+TAB
- return"""
+ return[].concat@makeCode(""" (function(func, args, ctor) {#{idt}ctor.prototype = func.prototype;#{idt}var child = new ctor, result = func.apply(child, args);#{idt}return Object(result) === result ? result : child;
-#{@tab}})(#{@variable.compileo,LEVEL_LIST}, #{splatArgs}, function(){})
- """
- base = Value.wrap@variable
+#{@tab}})("""),
+ (@variable.compileToFragmentso,LEVEL_LIST),
+ @makeCode(", "),splatArgs,@makeCode(", function(){})")
+
+ answer = []
+ base = newValue@variableif(name = base.properties.pop())andbase.isComplex()ref = o.scope.freeVariable'ref'
- fun = "(#{ref} = #{base.compileo,LEVEL_LIST})#{name.compileo}"
+ answer = answer.concat@makeCode("(#{ref} = "),
+ (base.compileToFragmentso,LEVEL_LIST),
+ @makeCode(")"),
+ name.compileToFragments(o)else
- fun = base.compileo,LEVEL_ACCESS
- fun = "(#{fun})"ifSIMPLENUM.testfun
+ fun = base.compileToFragmentso,LEVEL_ACCESS
+ fun = @wrapInBracesfunifSIMPLENUM.testfragmentsToTextfunifname
- ref = fun
- fun+=name.compileo
+ ref = fragmentsToTextfun
+ fun.push(name.compileToFragmentso)...elseref = 'null'
- "#{fun}.apply(#{ref}, #{splatArgs})"
Node to extend an object's prototype with an ancestor object.
+ answer = answer.concatfun
+ answer = answer.concat@makeCode(".apply(#{ref}, "),splatArgs,@makeCode(")")
A range literal. Ranges can be used to extract portions (slices) of arrays,
to specify a range for comprehensions, or as a value, to be expanded into the
corresponding array of integers at runtime.
exports.Range = classRangeextendsBase
@@ -502,31 +564,31 @@ corresponding array of integers at runtime.
An array slice literal. Unlike JavaScript's Array#slice, the second parameter
+ [@makeCode"(function() {#{pre}\n#{idt}for (#{body})#{post}}).apply(this#{args?''})"]
An array slice literal. Unlike JavaScript's Array#slice, the second parameter
specifies the index of the end of the slice, just as the first parameter
is the index of the beginning.
We have to be careful when trying to slice through the end of the array,
9e9 is used because not all implementations respect undefined or 1/0.
9e9 should be safe because 9e9 > 2**32, the max array length.
exports.Obj = classObjextendsBaseconstructor: (props, @generated = false) ->@objects = @properties = propsor[]
@@ -588,13 +651,14 @@ is the index of the beginning.
compileNode: (o) ->props = @properties
- return(if@frontthen'({})'else'{}')unlessprops.length
+ return[@makeCode(if@frontthen'({})'else'{}')]unlessprops.lengthif@generatedfornodeinpropswhennodeinstanceofValuethrownewError'cannot have an implicit value in an implicit object'idt = o.indent+=TABlastNoncom = @lastNonComment@properties
- props = forprop,iinprops
+ answer = []
+ forprop,iinpropsjoin = ifiisprops.length-1''elseifpropislastNoncomorpropinstanceofComment
@@ -608,42 +672,51 @@ is the index of the beginning.
use strict (and other directives) must be the first expression statement(s)
of a function body. This method ensures the prologue is correctly positioned
above the constructor.
returnExpr = null
- @ctor.body.traverseChildrenno,(node) ->
- returnnoifnodeinstanceofReturnand(returnExpr = node.expression)
- ifreturnExpr
- throwSyntaxError"cannot return a value from a constructor: \"#{returnExpr.compileNodeo}\" in class #{name}"
Instead of generating the JavaScript string directly, we build up the
equivalent syntax tree and compile that, in pieces. You can see the
constructor, property assignments, and inheritance getting built out below.
compileNode: (o) ->decl = @determineName()
@@ -731,7 +817,7 @@ constructor, property assignments, and inheritance getting built out below.
@hoistDirectivePrologue()@setContextname@walkBodyname,o
- @ensureConstructorname,o
+ @ensureConstructorname@body.spaced = yes@body.expressions.unshift@ctorunless@ctorinstanceofCode@body.expressions.pushlname
@@ -749,7 +835,7 @@ constructor, property assignments, and inheritance getting built out below.
klass = newParenscall,yesklass = newAssign@variable,klassif@variable
- klass.compileo
Compile an assignment, delegating to compilePatternMatch or
compileSplice if appropriate. Keep track of the name of the base object
we've been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.
compileNode: (o) ->
@@ -775,7 +861,8 @@ has not been seen yet within the current scope, declare it.
return @compilePatternMatchoif@variable.isArray()or@variable.isObject()return@compileSpliceoif@variable.isSplice()return@compileConditionaloif@contextin['||=','&&=','?=']
- name = @variable.compileo,LEVEL_LIST
+ compiledName = @variable.compileToFragmentso,LEVEL_LIST
+ name = fragmentsToTextcompiledNameunless@contextunless(varBase = @variable.unwrapAll()).isAssignable()throwSyntaxError"\"#{@variable.compileo}\" cannot be assigned."
@@ -787,10 +874,10 @@ has not been seen yet within the current scope, declare it. if @valueinstanceofCodeandmatch = METHOD_DEF.execname@value.klass = match[1]ifmatch[1]@value.name = match[2]?match[3]?match[4]?match[5]
- val = @value.compileo,LEVEL_LIST
- return"#{name}: #{val}"if@contextis'object'
- val = name+" #{@contextor'='} "+val
- ifo.level<=LEVEL_LISTthenvalelse"(#{val})"
Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.
See the ECMAScript Harmony Wiki
for details.
compilePatternMatch: (o) ->
@@ -798,10 +885,10 @@ for details.
When compiling a conditional assignment, take care to ensure that the
+ fragments = @joinFragmentArraysassigns,', '
+ ifo.level<LEVEL_LISTthenfragmentselse@wrapInBracesfragments
When compiling a conditional assignment, take care to ensure that the
operands are only evaluated once, even though we have to reference them
more than once.
Disallow conditional assignment of undefined variables.
ifnotleft.properties.lengthandleft.baseinstanceofLiteralandleft.base.value!="this"andnoto.scope.checkleft.base.valuethrownewError"the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been defined."if"?"in@contexttheno.isExistentialEquals = true
- Op.create(@context[...-1],left,newAssign(right,@value,'=')).compileo
A function definition. This is the only node that creates a new Scope.
+ answer = [].concat@makeCode("[].splice.apply(#{name}, [#{fromDecl}, #{to}].concat("),valDef,@makeCode(")), "),valRef
+ ifo.level>LEVEL_TOPthen@wrapInBracesanswerelseanswer
A function definition. This is the only node that creates a new Scope.
When for the purposes of walking the contents of a function body, the Code
has no children -- they're within the inner scope.
exports.Code = classCodeextendsBaseconstructor: (params, body, tag) ->
@@ -891,7 +982,7 @@ has no children -- they're within the inner scope.
Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by peeking at
the JavaScript arguments object. If the function is bound with the =>
arrow, generates a wrapper that saves the current value of this through
@@ -909,25 +1000,27 @@ a closure.
for {name: p}in@paramsifp.thisthenp = p.properties[0].nameifp.valuetheno.scope.addp.value,'var',yes
- splats = newAssignValue.wrap(newArr(p.asReferenceoforpin@params)),
- Value.wrapnewLiteral'arguments'
+ splats = newAssignnewValue(newArr(p.asReferenceoforpin@params)),
+ newValuenewLiteral'arguments'breakforparamin@paramsifparam.isComplex()val = ref = param.asReferenceo
- val = Op.create'?',ref,param.valueifparam.value
- exprs.pushnewAssignValue.wrap(param.name),val,'=',param: yes
+ val = newOp'?',ref,param.valueifparam.value
+ exprs.pushnewAssignnewValue(param.name),val,'=',param: yeselseref = paramifparam.valuelit = newLiteralref.name.value+' == null'
- val = newAssignValue.wrap(param.name),param.value,'='
+ val = newAssignnewValue(param.name),param.value,'='exprs.pushnewIflit,valparams.pushrefunlesssplatswasEmpty = @body.isEmpty()exprs.unshiftsplatsifsplats@body.expressions.unshiftexprs...ifexprs.length
- o.scope.parameterparams[i]=p.compileoforp,iinparams
+ forp,iinparams
+ params[i]=p.compileToFragmentso
+ o.scope.parameterfragmentsToTextparams[i]uniqs = []fornamein@paramNames()throwSyntaxError"multiple parameters named '#{name}'"ifnameinuniqs
@@ -941,16 +1034,22 @@ a closure.
A parameter in a function definition. Beyond a typical Javascript parameter,
these parameters can also attach themselves to the context of the function,
as well as be a splat, gathering up a group of parameters into an array.
exports.Param = classParamextendsBaseconstructor: (@name, @value, @splat) ->
@@ -959,8 +1058,8 @@ as well as be a splat, gathering up a group of parameters into an array.
children: ['name','value']
- compile: (o) ->
- @name.compileo,LEVEL_LIST
+ compileToFragments: (o) ->
+ @name.compileToFragmentso,LEVEL_LISTasReference: (o) ->return@referenceif@reference
@@ -971,12 +1070,12 @@ as well as be a splat, gathering up a group of parameters into an array.
node = newLiteralo.scope.freeVariablenode.valueelseifnode.isComplex()node = newLiteralo.scope.freeVariable'arg'
- node = Value.wrapnode
+ node = newValuenodenode = newSplatnodeif@splat@reference = nodeisComplex: ->
- @name.isComplex()
Finds the name or names of a Param; useful for detecting duplicates.
In a sense, a destructured parameter represents multiple JS parameters,
thus this method returns an Array of names.
Reserved words used as param names, as well as the Object and Array
@@ -985,31 +1084,31 @@ during the Code compilation step, so this is necessarily an incompl
list of a parameter's names.
A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.
exports.While = classWhileextendsBaseconstructor: (condition, options) ->
@@ -1068,7 +1173,7 @@ flexibility or more speed than a comprehension can provide.
return nounlessexpressions.lengthfornodeinexpressionsreturnnodeifnode.jumpsloop:yes
- no
The main difference from a JavaScript while is that the CoffeeScript
while can be used as a part of a larger expression -- while loops may
return an array containing the computed result of each iteration.
compileNode: (o) ->o.indent+=TAB
@@ -1085,28 +1190,28 @@ return an array containing the computed result of each iteration.
body.expressions.unshiftnewIf(newParens@guard).invert(),newLiteral"continue"elsebody = Block.wrap[newIf@guard,body]if@guard
- body = "\n#{body.compileo,LEVEL_TOP}\n#{@tab}"
- code = set+@tab+"while (#{@condition.compileo,LEVEL_PAREN}) {#{body}}"
+ body = [].concat@makeCode("\n"),(body.compileToFragmentso,LEVEL_TOP),@makeCode("\n#{@tab}")
+ answer = [].concat@makeCode(set+@tab+"while ("),@condition.compileToFragments(o,LEVEL_PAREN),
+ @makeCode(") {"),body,@makeCode("}")if@returns
- code+="\n#{@tab}return #{rvar};"
- code
In chains, there's no need to wrap bare obj literals in parens,
as the chained expression is wrapped.
@first.front = @frontunlessisChainif@operatoris'delete'ando.scope.check(@first.unwrapAll().value)throwSyntaxError'delete operand may not be argument or var'
@@ -1178,18 +1283,19 @@ as the chained expression is wrapped.
Checks a variable for existence -- not null and not undefined. This is
+ [].concat@makeCode(@tab+"throw "),(@expression.compileToFragmentso),@makeCode(";")
Checks a variable for existence -- not null and not undefined. This is
similar to .nil? in Ruby, and avoids having to consult a JavaScript truth
table.
An extra set of parentheses, specified explicitly in the source. At one time
we tried to clean up the results by detecting and removing redundant
parentheses, but no longer -- you can put in as many as you please.
@@ -1321,11 +1433,11 @@ parentheses, but no longer -- you can put in as many as you please.
expr = @body.unwrap()ifexprinstanceofValueandexpr.isAtomic()expr.front = @front
- returnexpr.compileo
- code = expr.compileo,LEVEL_PAREN
+ returnexpr.compileToFragmentso
+ fragments = expr.compileToFragmentso,LEVEL_PARENbare = o.level<LEVEL_OPand(exprinstanceofOporexprinstanceofCallor(exprinstanceofForandexpr.returns))
- ifbarethencodeelse"(#{code})"
CoffeeScript's replacement for the for loop is our array and object
comprehensions, that compile into for loops here. They also act as an
expression, able to return the result of each filtered iteration.
@@ -1345,7 +1457,7 @@ you can map and filter in a single pass.
throw SyntaxError'cannot pattern match over range loops'if@rangeand@pattern@returns = false
- children: ['body','source','guard','step']
Welcome to the hairiest method in all of CoffeeScript. Handles the inner
loop, filtering, stepping, and result saving for array, object, and range
comprehensions. Some of the generated code can be shared in common, and
some cannot.
compileNode: (o) ->
@@ -1354,8 +1466,8 @@ some cannot.
<
@returns = noiflastJumpsandlastJumpsinstanceofReturnsource = if@rangethen@source.baseelse@sourcescope = o.scope
- name = @nameand@name.compileo,LEVEL_LIST
- index = @indexand@index.compileo,LEVEL_LIST
+ name = @nameand(@name.compileo,LEVEL_LIST)
+ index = @indexand(@index.compileo,LEVEL_LIST)scope.find(name)ifnameandnot@patternscope.find(index)ifindexrvar = scope.freeVariable'results'if@returns
@@ -1363,7 +1475,7 @@ some cannot.
If/else statements. Acts as an expression by pushing down requested returns
to the last line of each clause.
Single-expression Ifs are compiled into conditional operators if possible,
@@ -1484,13 +1601,13 @@ because ternaries are already proper expressions, and don't need conversion.
The If only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a conditional operator is safe.
isStatement: (o) ->o?.levelisLEVEL_TOPor@bodyNode().isStatement(o)or@elseBodyNode()?.isStatement(o)
@@ -1507,37 +1624,38 @@ to be a statement. Otherwise a conditional operator is safe. this
ensureBlock: (node) ->
- ifnodeinstanceofBlockthennodeelsenewBlock[node]
Wrap the expressions body, unless it contains a pure statement,
in which case, no dice. If the body mentions this or arguments,
then make sure that the closure wrapper preserves the original values.
wrap: (expressions, statement, noReturn) ->returnexpressionsifexpressions.jumps()
@@ -1549,7 +1667,7 @@ then make sure that the closure wrapper preserves the original values.
meth = newLiteralifmentionsArgsthen'apply'else'call'args = [newLiteral'this']args.pushnewLiteral'arguments'ifmentionsArgs
- func = Value.wrapfunc,[newAccessmeth]
+ func = newValuefunc,[newAccessmeth]func.noReturn = noReturncall = newCallfunc,argsifstatementthenBlock.wrap[call]elsecall
@@ -1560,25 +1678,23 @@ then make sure that the closure wrapper preserves the original values.
literalThis: (node) ->(nodeinstanceofLiteralandnode.valueis'this'andnotnode.asKey)or(nodeinstanceofCodeandnode.bound)or
- (nodeinstanceofCallandnode.isSuper)
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; }
- """
The CoffeeScript language has a good deal of optional syntax, implicit syntax,
and shorthand syntax. This can greatly complicate a grammar and bloat
the resulting parse table. Instead of making the parser handle it all, we take
a series of passes over the token stream, using this Rewriter to convert
shorthand into the unambiguous long form, add implicit indentation and
-parentheses, and generally clean things up.
Rewrite the token stream in multiple passes, one logical filter at
a time. This could certainly be changed into a single pass through the
stream, with a big ol' efficient switch, but it's much nicer to work with
like this. The order of these passes matters -- indentation must be
@@ -16,10 +19,9 @@ corrected before implicit parentheses can be wrapped around blocks of code.
Rewrite the token stream, looking one token ahead and behind.
Allow the return value of the block to tell us how many tokens to move
forwards (or backwards) in the stream, to make sure we don't miss anything
as tokens are inserted and removed, and the stream changes length under
@@ -40,18 +42,17 @@ our feet.
The lexer has tagged the opening parenthesis of a method call. Match it with
its paired close. We have the mis-nested outdent case included here for
calls that close on the same line, just before their outdent.
closeOpenCalls: ->
-
condition = (token, i) ->token[0]in[')','CALL_END']ortoken[0]is'OUTDENT'and@tag(i-1)is')'
@@ -61,9 +62,8 @@ calls that close on the same line, just before their outdent.
@scanTokens(token, i) ->@detectEndi+1,condition,actioniftoken[0]is'CALL_START'
- 1
Match tags in token stream starting at i with pattern, skipping HERECOMMENTs
+Pattern may consist of strings (equality), an array of strings (one of)
+or null (wildcard)
yes iff current line of tokens contain an element of tags on same
+expression level. Stop searching at LINEBREAKS or explicit start of
+containing balanced expression.
Methods may be optionally called without parentheses, for simple cases.
-Insert the implicit parentheses here, so that the parser doesn't have to
-deal with them.
An INDENT closes an implicit call unless
+1. We have seen a CONTROL argument on the line.
+2. The last token before the indent is part of the list below
Implicit call taking an implicit indented object as first argument.
+f
+ a: b
+ c: d
+and
+f
+ 1
+ a: b
+ b: c
+Don't accept implicit calls of this type, when on the same line
+as the control strucutures below as that may misinterpret constructs like:
+if f
+ a: 1
+as
+if f(a: 1)
+which is probably always unintended.
+Furthermore don't allow this in literal arrays, as
+that creates grammatical ambiguities.
Close implicit objects when at end of line, line didn't end with a comma
+and the implicit object didn't start the line or the next line doesn't look like
+the continuation of an object.
Close implicit object if comma is the last character
+and what comes after doesn't look like it belongs.
+This is used for trailing commas and calls, like:
+x =
+ a: b,
+ c: d,
+e = 2
Because our grammar is LALR(1), it can't handle some single-line
expressions that lack ending delimiters. The Rewriter adds the implicit
blocks, so it doesn't need to. ')' can close a single-line block,
but we need to make sure it's balanced.
addImplicitIndentation: ->
@@ -212,7 +274,7 @@ but we need to make sure it's balanced.
\ No newline at end of file
diff --git a/documentation/docs/sourcemap.html b/documentation/docs/sourcemap.html
new file mode 100644
index 00000000..0d1bca45
--- /dev/null
+++ b/documentation/docs/sourcemap.html
@@ -0,0 +1,155 @@
+ sourcemap.coffee
Maps locations in a generated source file back to locations in the original source file.
+
+
This is intentionally agnostic towards how a source map might be represented on disk. A
+SourceMap can be converted to a "v3" style sourcemap with #generateV3SourceMap(), for example
+but the SourceMap class itself knows nothing about v3 source maps.
fn will be called once for every recorded mapping, in the order in
+which they occur in the generated source. fn will be passed an object
+with four properties: sourceLine, sourceColumn, generatedLine, and
+generatedColumn.
Write the next segment.
+Segments can be 1, 4, or 5 values. If just one, then it is a generated column which
+doesn't match anything in the source code.
+
+
Fields are all zero-based, and relative to the previous occurence unless otherwise noted:
+ * starting-column in generated source, relative to previous occurence for the current line.
+ * index into the "sources" list
+ * starting line in the original source
+ * starting column in the original source
+ * index into the "names" list associated with this segment.
Note that SourceMap VLQ encoding is "backwards". MIDI style VLQ encoding puts the
+most-significant-bit (MSB) from the original value into the MSB of the VLQ encoded value
+(see http://en.wikipedia.org/wiki/File:Uintvar_coding.svg). 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.
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.
I'm fairly excited about this direction for the language, and am looking
forward to writing (and more importantly, reading) more programs in this style.
- As 1.5.0 is the first version of CoffeeScript that supports it, let us know
- if you have any ideas for improving the feature.
+ More information about Literate CoffeeScript, including an
+ example program,
+ are available in this blog post.
-
+
Lexical Scoping and Variable Safety
The CoffeeScript compiler takes care to make sure that all of your variables
are properly declared within lexical scope — you never need to write
@@ -801,7 +814,7 @@ Expressions
<%= code_for('patterns_and_splats', 'contents.join("")') %>
-
+
Function binding
In JavaScript, the this keyword is dynamically scoped to mean the
object that the current function is attached to. If you pass a function as
@@ -950,6 +963,26 @@ Expressions
code itself — not the cake task.
+
+
+ Source Maps
+
+
+
+ CoffeeScript 1.6.0 and above include support for generating source maps,
+ a way to tell your JavaScript engine what part of your CoffeeScript
+ program matches up with the code being evaluated. Browsers that support it
+ can automatically use source maps to show your original source code
+ in the debugger. To generate source maps alongside your JavaScript files,
+ pass the --map or -m flag to the compiler.
+
+
+
+ For a full introduction to source maps, how they work, and how to hook
+ them up in your browser, read the
+ HTML5 Tutorial.
+
+ First release of source maps. Pass the
+ --map flag to the compiler, and off you go. Direct all your
+ thanks over to Jason Walton.
+
+
+ Fixed a 1.5.0 regression with multiple implicit calls against an
+ indented implicit object. Combinations of implicit function calls
+ and implicit objects should generally be parsed better now —
+ but it still isn't good style to nest them too heavily.
+
+
+ .coffee.md is now also supported as a Literate CoffeeScript
+ file extension, for existing tooling.
+ .litcoffee remains the canonical one.
+
+
+ Several minor fixes surrounding member properties, bound methods and
+ super in class declarations.
+
I'm fairly excited about this direction for the language, and am looking
forward to writing (and more importantly, reading) more programs in this style.
- As 1.5.0 is the first version of CoffeeScript that supports it, let us know
- if you have any ideas for improving the feature.
+ More information about Literate CoffeeScript, including an
+ example program,
+ are available in this blog post.
@@ -667,7 +680,7 @@ log object.class
load
-
+
Lexical Scoping and Variable Safety
The CoffeeScript compiler takes care to make sure that all of your variables
are properly declared within lexical scope — you never need to write
@@ -1519,7 +1532,7 @@ Snake = (function(_sup
__extends(Snake, _super);
functionSnake() {
- Snake.__super__.constructor.apply(this, arguments);
+ return Snake.__super__.constructor.apply(this, arguments);
}
Snake.prototype.move = function() {
@@ -1536,7 +1549,7 @@ Horse = (function(_sup
__extends(Horse, _super);
functionHorse() {
- Horse.__super__.constructor.apply(this, arguments);
+ return Horse.__super__.constructor.apply(this, arguments);
}
Horse.prototype.move = function() {
@@ -1578,7 +1591,7 @@ Snake = (function(_super) {
__extends(Snake, _super);
function Snake() {
- Snake.__super__.constructor.apply(this, arguments);
+ return Snake.__super__.constructor.apply(this, arguments);
}
Snake.prototype.move = function() {
@@ -1595,7 +1608,7 @@ Horse = (function(_super) {
__extends(Horse, _super);
function Horse() {
- Horse.__super__.constructor.apply(this, arguments);
+ return Horse.__super__.constructor.apply(this, arguments);
}
Horse.prototype.move = function() {
@@ -1776,7 +1789,7 @@ _ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call
;alert(contents.join(""));'>run: contents.join("")
-
+
Function binding
In JavaScript, the this keyword is dynamically scoped to mean the
object that the current function is attached to. If you pass a function as
@@ -2025,18 +2038,18 @@ html = "\n cup of coffeescript\n";
are preserved in the generated code.
###
-CoffeeScript Compiler v1.5.0
+CoffeeScript Compiler v1.6.0Released under the MIT License###
/*
-CoffeeScript Compiler v1.5.0
+CoffeeScript Compiler v1.6.0Released under the MIT License*/
-
+ CoffeeScript 1.6.0 and above include support for generating source maps,
+ a way to tell your JavaScript engine what part of your CoffeeScript
+ program matches up with the code being evaluated. Browsers that support it
+ can automatically use source maps to show your original source code
+ in the debugger. To generate source maps alongside your JavaScript files,
+ pass the --map or -m flag to the compiler.
+
+
+
+ For a full introduction to source maps, how they work, and how to hook
+ them up in your browser, read the
+ HTML5 Tutorial.
+
+ First release of source maps. Pass the
+ --map flag to the compiler, and off you go. Direct all your
+ thanks over to Jason Walton.
+
+
+ Fixed a 1.5.0 regression with multiple implicit calls against an
+ indented implicit object. Combinations of implicit function calls
+ and implicit objects should generally be parsed better now —
+ but it still isn't good style to nest them too heavily.
+
+
+ .coffee.md is now also supported as a Literate CoffeeScript
+ file extension, for existing tooling.
+ .litcoffee remains the canonical one.
+
+
+ Several minor fixes surrounding member properties, bound methods and
+ super in class declarations.
+
+
+
+
1.5.0
diff --git a/lib/coffee-script/browser.js b/lib/coffee-script/browser.js
index 3b51fee2..338e836d 100644
--- a/lib/coffee-script/browser.js
+++ b/lib/coffee-script/browser.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
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; };
diff --git a/lib/coffee-script/cake.js b/lib/coffee-script/cake.js
index afa53ca3..86d13373 100644
--- a/lib/coffee-script/cake.js
+++ b/lib/coffee-script/cake.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var CoffeeScript, cakefileDirectory, existsSync, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
diff --git a/lib/coffee-script/coffee-script.js b/lib/coffee-script/coffee-script.js
index b1c51bfc..24e90267 100644
--- a/lib/coffee-script/coffee-script.js
+++ b/lib/coffee-script/coffee-script.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var Lexer, baseFileName, compile, ext, fs, helpers, lexer, loadFile, parser, path, sourcemap, vm, _i, _len, _ref,
__hasProp = {}.hasOwnProperty;
@@ -35,7 +35,7 @@
}
}
- exports.VERSION = '1.5.0';
+ exports.VERSION = '1.6.0';
exports.helpers = require('./helpers');
diff --git a/lib/coffee-script/command.js b/lib/coffee-script/command.js
index 54f8a6a5..6d566d86 100644
--- a/lib/coffee-script/command.js
+++ b/lib/coffee-script/command.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
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;
diff --git a/lib/coffee-script/grammar.js b/lib/coffee-script/grammar.js
index 9ec53bf2..323bf138 100644
--- a/lib/coffee-script/grammar.js
+++ b/lib/coffee-script/grammar.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
diff --git a/lib/coffee-script/helpers.js b/lib/coffee-script/helpers.js
index 08ef7ee8..10f5e352 100644
--- a/lib/coffee-script/helpers.js
+++ b/lib/coffee-script/helpers.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var buildLocationData, extend, flatten, _ref;
diff --git a/lib/coffee-script/index.js b/lib/coffee-script/index.js
index 8f382c57..6bc76f2e 100644
--- a/lib/coffee-script/index.js
+++ b/lib/coffee-script/index.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var key, val, _ref;
diff --git a/lib/coffee-script/lexer.js b/lib/coffee-script/lexer.js
index 72f4dcf0..53a76ad5 100644
--- a/lib/coffee-script/lexer.js
+++ b/lib/coffee-script/lexer.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(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, 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; };
diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js
index ba66e4a3..2e3a8fe5 100644
--- a/lib/coffee-script/nodes.js
+++ b/lib/coffee-script/nodes.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, last, locationDataToString, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
diff --git a/lib/coffee-script/optparse.js b/lib/coffee-script/optparse.js
index a3390cc5..f52b5134 100644
--- a/lib/coffee-script/optparse.js
+++ b/lib/coffee-script/optparse.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
diff --git a/lib/coffee-script/repl.js b/lib/coffee-script/repl.js
index 27876937..e9e771cf 100644
--- a/lib/coffee-script/repl.js
+++ b/lib/coffee-script/repl.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var CoffeeScript, addMultilineHandler, merge, nodeREPL, replDefaults, vm;
diff --git a/lib/coffee-script/rewriter.js b/lib/coffee-script/rewriter.js
index e40b3d8c..e226222d 100644
--- a/lib/coffee-script/rewriter.js
+++ b/lib/coffee-script/rewriter.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _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; },
diff --git a/lib/coffee-script/scope.js b/lib/coffee-script/scope.js
index 7b741bea..a51c3698 100644
--- a/lib/coffee-script/scope.js
+++ b/lib/coffee-script/scope.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var Scope, extend, last, _ref;
diff --git a/lib/coffee-script/sourcemap.js b/lib/coffee-script/sourcemap.js
index b980565d..a7656ef9 100644
--- a/lib/coffee-script/sourcemap.js
+++ b/lib/coffee-script/sourcemap.js
@@ -1,4 +1,4 @@
-// Generated by CoffeeScript 1.5.0
+// Generated by CoffeeScript 1.6.0
(function() {
var BASE64_CHARS, LineMapping, MAX_BASE64_VALUE, VLQ_CONTINUATION_BIT, VLQ_SHIFT, VLQ_VALUE_MASK, decodeBase64Char, encodeBase64Char;
diff --git a/package.json b/package.json
index 4e9da41d..f4044a3c 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"description": "Unfancy JavaScript",
"keywords": ["javascript", "language", "coffeescript", "compiler"],
"author": "Jeremy Ashkenas",
- "version": "1.5.0",
+ "version": "1.6.0",
"licenses": [{
"type": "MIT",
"url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
diff --git a/src/coffee-script.coffee b/src/coffee-script.coffee
index 16ee5c81..60cfd82a 100644
--- a/src/coffee-script.coffee
+++ b/src/coffee-script.coffee
@@ -25,7 +25,7 @@ if require.extensions
require.extensions[ext] = loadFile
# The current CoffeeScript version number.
-exports.VERSION = '1.5.0'
+exports.VERSION = '1.6.0'
# Expose helpers for testing.
exports.helpers = require './helpers'
diff --git a/test/sourcemap.coffee b/test/sourcemap.coffee
index af8af78a..2770fb6c 100644
--- a/test/sourcemap.coffee
+++ b/test/sourcemap.coffee
@@ -1,3 +1,5 @@
+return if global.testingBrowser
+
sourcemap = require '../src/sourcemap'
vlqEncodedValues = [