* Use Markdown-It instead of Marked for generating the docs; update package versions
* Fix links to v2 docs
* Bump version to 1.12.5; update changelog and compiled docs output
* Update compiled output for 1.12.5
* Improve styling for tables
This is an upstream port of https://github.com/decaffeinate/coffeescript/pull/24
In a case like `new A().b(c)`, the jison structure ends up being different from
the resulting AST. To the jison parser, this is the `new` unary operator applied
to the expression `A().b(c)`. When the unary operator is applied, the
`Call.prototype.newInstance` function traverses into the leftmost function call
and sets the `isNew` flag to true, and the `Op` constructor returns the `Call`
node so that the call is used in place of the unary operator. However, the code
wasn't updating the node location data, so this commit fixes that.
It's sort of hard to get the location data in `newInstance`, so we set a flag on
every affected node in `newInstance` and override `updateLocationDataIfMissing`
(which is called with the location data after the fact) so that it updates just
the starting position.
This is an upstream port of https://github.com/decaffeinate/coffeescript/pull/17
The lexer generates fake tokens for interpolated heregexes, and the ending
tokens were being placed where the start (inclusive) and end (inclusive) index
were one past the end of the heregex. This meant that in a case like
`[a ///#{b}///]`, the end tokens of the heregex and also the implicit function
call end were all being placed at the `]`, so the AST location data would say
that the function call ends at the end of the `]`.
To fix, I can just subtract 1 from the position of those ending heregex tokens
so that their end lines up with the end of the heregex itself. This is similar
to previous fixes that changed `OUTDENT` and `CALL_END` tokens so that the end
of the token lines up with the end of the AST node.
Exports that referenced variables assigned in the module would prevent
the referenced variables from being declared, resulting in
ReferenceErrors at run time.
Fixes#4394.
* Revert aee27fbff0
* Patch Jison’s output so that it requires `fs` only if we’re truly in a CommonJS/Node environment, not a browser environment that may happen to have globals named `require` and `exports` (as would be the case if require.js is being used). Fixes#4391.
* Temporary fix for exceptions getting thrown when trying to generate a stack trace for a file that has been deleted since compilation; fixes#3890, but not well. A better solution would not try to recompile the file when trying to retrieve its stack trace.
* Save the test REPL history in the system temp folder, not in the CoffeeScript project folder
* Rewrite `getSourceMap` to never read a file from disk, and therefore not throw IO-related exceptions; source maps are either retrieved from memory, or the related source code is retrieved from memory to generate a new source map. Fixes#3890 the proper way.
* Add test to verify that stack traces reference the correct line number. Closes#4418.
* Get the parser working in the browser compiler again; rather than detecting a CommonJS environment generally, just check for `fs` before trying to use it
* Follow Node’s standard of 4-space indentation of stack trace data
* Better .gitignore
* Fix caching of compiled code and source maps; add more tests to verify correct line numbers in stack traces
* Better fallback value for the parser source
* Fix the stack traces and tests when running in a browser
* Update the browser compiler so that @murrayju doesn’t have any extra work to do to test this branch
This loosens the compilation of `for` expressions to allow the index
variable to be an `@` value, e.g.
do @visit for @node, @index in nodes
Within `@visit`, the index of the current node (`@node`) would be
available as `@index`.
Fixes#4411.
* Try to detect when `from` in a `for` loop declaration is an identifier, not a keyword
* Handle destructured arrays
* from as a destructured, aliased object variable name in a for loop declaration
* Support JavaScript code blocks set apart by triple backticks (``` ... ```)
* Add test for escaped backticks
* Remove TODOs for things we’re never going to support
* Convert escaped backticks to backticks; update tests
* Block inline JavaScript can end with an escaped backtick character
* Updated JavaScript token regexes per @lydell
* In JavaScript blocks, escape backslashes when they immediately precede backticks; additional tests
* Test that we don’t break backslash escaping in JavaScript literals
* Add initial support for template literals with no
interpolation
* Change ‘unexpected string’ error message tests to
use number not identifier prefix.
Identifer prefixes are now valid as tagged
template literals
* Test tagged template literals for non-interpolated
strings and tag function.
* Tagged template literals work for pure Strings.
Pull tagged template definition up to Invocation
level in grammar, enabling chained invocation calls.
We can view a tagged template is a special form
of function call.
* Readying for StringWithInterpolations work.
* Tweaks.
* Fix style
* Pass StringWithInterpolations parameter straight
into Call constructor.
StringWithInterpolations will be output as
template literal, so already in correct form for
outputting tagged template literal.
* Strip down compileNode for StringWithInterpolations
* Done StringLiteral case for interpolated Strings
* Remove need for TemplateLiteral
* Simplify code.
* Small code tidy
* Interpolated strings now outputting as template literals.
Still needs comprehensive testing.
* Move error message tests into error_messages.coffee; remove test that is testing for a Node runtime error
* Split up tests that were testing multiple things per test, so that each test tests only one thing
* Edge cases: tagged template literals containing interpolated strings or even internal tagged template literals
* Make more concise, more idiomatic style
* Pull back extreme indentation
* Restore and fix commented-out tests
* Edge case: tagged template literal with empty string
* Only use new ES2015 interpolated string syntax if we’re inside a tagged template literal; this keeps this PR safe to merge into CoffeeScript 1.x. Remove the code from this commit to make all interpolated strings use ES2015 syntax, for CoffeeScript 2.
* Compiler now _doesn’t_ use template literals.
* Expand tagged template literal tests
* Move ‘Unexpected string’ error message tests into
tagged template literal section.
‘Unexpected string’ is not reported in these test
scenarios anymore. Instead, we error that the
prefixing literal is not a function.
* Don’t unwrap StringWithInterpolations.
Saw bug with program consisting of “#{2}” not
compiling with template literals. Root cause was
that Block.compileNode was unwrapping interpolated
string and so didn’t use compileNode logic at
StringWithInterpolations level.
* No need to bracket interpolated strings any more.
When interpolated string looks like `hello ${2}`,
no extract brackets are needed, as the `s mark the
beginning and end.
* Show html templating with tagged template literals
* Multiline should match multiline
* Comment out unnecessary `unwrap`, which is only needed for CoffeeScript 2 all-ES2015 syntax output
* Added support for for-from loop, see #3832
* for-from: remove extra newline and add support for ranges
* for-from: tidy up the lexer
* for-from: add support for patterns
* for-from: fix bad alignment
* for-from: add two more tests
* for-from: fix test "for-from loops over generators"
See explanation here: https://github.com/jashkenas/coffeescript/pull/4306#issuecomment-257066877
* for-from: delete leftover console.log
* Refactor the big `if` block in the lexer to be as minimal a change from `master` as we can get away with
* Cleanup to make more idiomatic, remove trailing whitespace, minor performance improvements
* for-from: move code from one file to another
* for-from: clean up whitespace
* for-from: lexer bikeshedding
* Move "own is not supported in for-from loops" test into error_messages.coffee; improve error message so that "own" is underlined
* Revert unnecessary changes, to minimize the lines of code modified by this PR
This is an upstream port of https://github.com/decaffeinate/coffeescript/pull/10
See that PR for links to the issues that this fixes.
Just like OUTDENT and CALL_END tokens, close-curly-brace tokens can be generated
without having a real location, and if that position overlaps with a later
token, it can cause the AST to have bad location data. Just like the other two
token types, we now give `}` tokens the position of the previous real token,
which makes all AST nodes have reasonable locations.
This is an upstream port of https://github.com/decaffeinate/coffeescript/pull/9
The existing logic for computing the end location of a string was to take the
end of the string contents, then add the delimiter length to last_column. For
example, `"""abc"""` would have an end position three characters after the `c`.
However, if a string ended in a newline, then the end location for the string
contents would be one line above the end location for the string, so the proper
fix is to move the end location to the next line, not just to shift it to the
right.
This avoids a bug where the location data would sometimes reference a
non-existent location (one past the end of its line). It fixes the AST location
data, although as far as I know, it never has caused correctness issues in the
CoffeeScript output.
This is an upstream port for the patch https://github.com/decaffeinate/coffeescript/pull/8
See https://github.com/decaffeinate/decaffeinate/issues/291 for the bug that this fixed.
For the most part, CoffeeScript and JavaScript have the same precedence rules,
but in some cases, the intermediate AST format didn't represent the actual
evaluation order. For example, in the expression `a or b and c`, the `and` is
evaluated first, but the parser treated the two operators with equal precedence.
This was still correct end-to-end because CoffeeScript simply emitted the result
without parens, but any intermediate tools using the CoffeeScript parser could
become confused.
Here are the JS operator precedence rules:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
For the most part, CoffeeScript already follows these. `COMPARE` operators
already behave differently due to chained comparisons, so I think we don't need
to worry about following JS precedence for those. So I think the only case where
it was behaving differently in an important way was for the binary/bitwise
operators that are being changed here.
As part of this change, I also introduced a new token tag, `BIN?`, for the
binary form of the `?` operator.
Fixes https://github.com/decaffeinate/decaffeinate/issues/446
In addition to OUTDENT tokens, CALL_END tokens can also be virtual tokens
without a real location, and sometimes they end up with a location that's
incorrect.
This commit adds another post-processing step after normal lexing that sets the
locationData on all OUTDENT tokens to be at the last character of the previous
token. This does feel like a little bit of a hack. Ideally the location data
would be set correctly in the first place and not in a post-processing step, but
I tried that and some temporary intermediate tokens were causing problems, so I
decided to set the location data once those intermediate tokens were removed.
Also, having this as a separate processing step makes it more robust and
isolated.
This fixes the problem in https://github.com/decaffeinate/decaffeinate/issues/371 .
In that issue, the CoffeeScript tokens had three OUTDENT tokens in a row, and
the last two overlapped with the `]`. Since at least one of those OUTDENT tokens
was considered part of the function body, the function expression had an ending
position just after the end of the `]`.
OUTDENT tokens are sort of a weird case in the lexer anyway, since they often
don't correspond to an actual location in the source code. It seems like the
code in `lexer.coffee` makes an attempt at finding a good place for them, but in
some cases, it has a bad result. This seems hard to avoid in the general case.
For example, in this code:
```coffee
[->
a]
```
There must be an OUTDENT between the `a` and the `]`, but CoffeeScript tokens
have an inclusive start and end, so they must always be at least one character
wide (I think). In this case, the lexer was choosing the `]` as the location,
and the parser ended up generating correct location data, I believe because
it ignores the outermost INDENT and OUTDENT tokens. However, with multiple
OUTDENT tokens in a row, the parser ends up producing location data that is
wrong.
It seems to me like there isn't a solid answer to "what location do OUTDENT
tokens have", since it hasn't mattered much, but for this commit, I'm defining
it: they always have the location of the last character of the previous token.
This should hopefully be fairly safe because tokens are still in the same order
relative to each other. Also, it's worth noting that this makes the start
location for OUTDENT tokens awkward. However, OUTDENT tokens are always used to
mark the end of something, so their `last_line` and `last_column` values are
always what matter when determining AST node bounds, so it is most important for
those to be correct.
`"""` (and `"`) strings are lexed into an array of tokens, consisting of
strings and interpolations. Previously, the minimum indententation
inside `"""` strings was stripped from the beginning of _all_ of those
string tokens. Usually, the indentation is longer than any other
sequence of spaces in a `"""` string, so the problem didn't occur in
most cases. This commit makes sure to only strip indentation after
newlines.
Fixes#4314.
Very large decimal number literals, binary number literals and octal
literals are lexed into an INFINITY token (instead of a NUMBER token)
and compiled into `2e308`. That is is supposed to be the case for very
large hexdecimal dumber literals as well, but previously wasn't.
Before:
$ node -p 'require("./").tokens(`0x${Array(256 + 1).join("f")}`)[0][0]'
NUMBER
After:
$ node -p 'require("./").tokens(`0x${Array(256 + 1).join("f")}`)[0][0]'
INFINITY
This commit also cleans up `numberToken` in lexer.coffee a bit.
`isLiteralArguments` mistakenly looked at `Literal`s instead of
`IdentifierLiteral`s.
This also gets rid of the ugly `.asKey` hack in nodes.coffee.
Fixes#4320.
Before:
```
$ cat tmp.coffee.md
test
a
$ ./bin/coffee tmp.coffee.md
ReferenceError: a is not defined
at Object.<anonymous> (/src/coffee-script/tmp.coffee.md:2:3)
...
```
Note how the line and column numbers (2 and 3, respectively) are not
correct.
After:
```
$ ./bin/coffee tmp.coffee.md
ReferenceError: a is not defined
at Object.<anonymous> (/home/lydell/forks/coffee-script/tmp.coffee.md:3:5)
...
```
Line 3, column 5 is the actual position of the `a` in tmp.coffee.md.
Supersedes and fixes#4204.