The following is now allowed:
o =
a: 1
b: 2
"#{'c'}": 3
"#{'d'}": 4
e: 5
"#{'f'}": 6
g: 7
It compiles to:
o = (
obj = {
a: 1,
b: 2
},
obj["" + 'c'] = 3,
obj["" + 'd'] = 4,
obj.e = 5,
obj["" + 'f'] = 6,
obj.g = 7,
obj
);
- Closes#3039. Empty interpolations in object keys are now _supposed_ to be
allowed.
- Closes#1131. No need to improve error messages for attempted key
interpolation anymore.
- Implementing this required fixing the following bug: `("" + a): 1` used to
error out on the colon, saying "unexpected colon". But really, it is the
attempted object key that is unexpected. Now the error is on the opening
parenthesis instead.
- However, the above fix broke some error message tests for regexes. The easiest
way to fix this was to make a seemingly unrelated change: The error messages
for unexpected identifiers, numbers, strings and regexes now say for example
'unexpected string' instead of 'unexpected """some #{really long} string"""'.
In other words, the tag _name_ is used instead of the tag _value_.
This was way easier to implement, and is more helpful to the user. Using the
tag value is good for operators, reserved words and the like, but not for
tokens which can contain any text. For example, 'unexpected identifier' is
better than 'unexpected expected' (if a variable called 'expected' was used
erraneously).
- While writing tests for the above point I found a few minor bugs with string
locations which have been fixed.
- Invalid `\x` and `\u` escapes now throw errors.
- U+2028 and U+2029 (which JavaScript treats as newline characters) are now
escaped to `\u2028` and `\u2029`, respectively.
- Octal escapes are now forbidden not only in strings, but in regexes as well.
- `\0` escapes are now escaped if needed (so that they do not form an octal
literal by mistake). Note that `\01` is an octal escape in a regex, while `\1`
is a backreference. (Added a test for backreferences while at it.)
- Fixed a bug where newlines in strings weren't removed if preceded by an
escaped character.
The third element in a token should just be an object containing line
number and column info. This PR fixes the problem with one of the tokens
being set incorrectly.
As discussed in https://github.com/jashkenas/coffeescript/issues/3039#issuecomment-68916918.
This is the first step to implement dynamic object literal keys (see #3597).
This also fixes#1392.
In short, `super` is now allowed:
# in class definitions:
class A
instanceMethod: -> super
@staticMethod: -> super
@staticMethod2 = -> super
# in assignment where the next to last access is 'prototype':
A::m = -> super
A.prototype.m = -> super
a.b()[5]::m = -> super
A::[x()] = -> super
class B
@::m = -> super
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.