The following two lines might seem equivalent:
for n in [1, 2, 3] by a then a = 4; n
for n in [1, 2, 3] by +a then a = 4; n
But they used not to be, because `+a` was cached into a `ref`, while the plain
`a` wasn’t. Now even simple identifiers are cached, making the two lines
equivalent as expected.
As evidenced in #3804, commit 8ab15d7 broke the CoffeeScript API. The REPL uses
those APIs, but wasn't updated in that commit. Still, that shouldn't have
_broken_ the REPL. The reason it broke is because the added _option_
'referencedVars' wasn't actually _optional;_ if it was omitted code that relies
on it being set broke. This commit defaults that option to an empty array, which
makes things behave exactly like before when the 'referencedVars' option is
omitted.
Supersedes #3805. Here is a comparison of master, #3805 and this commit:
# master
$ bin/coffee
coffee> 1 %% 2
TypeError: Array.prototype.indexOf called on null or undefined
# #3805
$ bin/coffee
coffee> 1 %% 2
1
coffee> (_results = null; i) for i in [1, 2, 3]
TypeError: Cannot call method 'push' of null
# this commit
$ bin/coffee
coffee> 1 %% 2
1
coffee> (_results = null; i) for i in [1, 2, 3]
[ 1, 2, 3 ]
Instead of compiling to `"" + + (+"-");`, `"#{+}-"'` now gives an appropriate
error message:
[stdin]:1:5: error: unexpected end of interpolation
"#{+}-"
^
This is done by _always_ (instead of just sometimes) wrapping the interpolations
in parentheses in the lexer. Unnecessary parentheses won't be output anyway.
I got tired of updating the tests in test/location.coffee (which I had enough of
in #3770), which relies on implementation details (the exact amount of tokens
generated for a given string of code) to do their testing, so I refactored them
to be less fragile.
Since zaach/jison commit 3548861b, `parser.lexer` is never modified anymore (a
copy of it is made, and that copy is modified instead). CoffeeScript itself
modifies `parser.lexer` and then accesses those modifications in the custom
`parser.yy.parseError` function, but that of course does not work anymore. This
commit puts the data that `parser.yy.parseError` needs directly on the `parser`
so that it is not lost.
Supersedes #3603. Fixes#3608 and zaach/jison#243.
Using the static property `Scope.root` for the top-level scope of a file is a
hack, which makes it impossible to have several independent `Scope` instances
at the same time (should we ever need that).
This commit makes every instance have a reference to its root instead.
Any variables generated by CoffeeScript are now made sure to be named to
something not present in the source code being compiled. This way you can no
longer interfere with them, either on purpose or by mistake. (#1500, #1574)
For example, `({a}, _arg) ->` now compiles correctly. (#1574)
As opposed to the somewhat complex implementations discussed in #1500, this
commit takes a very simple approach by saving all used variables names using a
single pass over the token stream. Any generated variables are then made sure
not to exist in that list.
`(@a) -> a` used to be equivalent to `(@a) -> @a`, but now throws a runtime
`ReferenceError` instead (unless `a` exists in an upper scope of course). (#3318)
`(@a) ->` used to compile to `(function(a) { this.a = a; })`. Now it compiles to
`(function(_at_a) { this.a = _at_a; })`. (But you cannot access `_at_a` either,
of course.)
Because of the above, `(@a, a) ->` is now valid; `@a` and `a` are not duplicate
parameters.
Duplicate this-parameters with a reserved word, such as `(@case, @case) ->`,
used to compile but now throws, just like regular duplicate parameters.