rainforestapp / decaf

Coffeescript to ES.next transpiler. Now maintained over at
https://github.com/juliankrispel/decaf
MIT License
106 stars 10 forks source link

Template strings #2

Open juliankrispel opened 8 years ago

juliankrispel commented 8 years ago

Missing feature!

Template strings like this:

bom = 'yoyoyo #{dwq}'

should transpile to

bom = `yoyoyo ${dwq}`;
juliankrispel commented 8 years ago

So the problem with this one is that coffeescript has multiple compile steps.

Some of the compilation (like the compiling of strings) is actually done inside the lexer -_-.

By the time coffeescript gives me the AST, the string "hello #{world}" will already have been turned into "hello " + world by the lexer.

There are two solutions to this issue:

1 - Monkey patching coffee script (which would mean a massive extra file). 2 - A decaf-specific fork of the coffee-script compiler with that part disabled. 3 - Turning #{} into ${} so that the coffeescript lexer ignores it and later converting double-quote strings with ${} to backtick strings.

Any thoughts @flying-sheep @eventualbuddha ?

flying-sheep commented 8 years ago

or 4 - working together with @jashkenas to sort this out.

we’d reopen jashkenas/coffeescript#2365 for single line comments, and help fixing jashkenas/coffeescript#4192

lydell commented 8 years ago

Another idea: Automatically output ES6 template strings instead of string concatenation, regardless of whether the CoffeeScript input was "#{a} and #{b}" or a + ' and ' + b. Pros: No changes to CoffeeScript needed. Automatic code improvement. Cons: Dunno?

flying-sheep commented 8 years ago

sure! why didn’t i think of this? :smiley:

eventualbuddha commented 8 years ago

I would vote for detecting string additions that actually were originally string interpolations. This can be done by looking at the unrewritten tokens for the node (decaffeinate-parser does that). I'm afk so can't provide details now.

Also, esnext will automatically turn string additions into interpolations as you suggest. You don't want to do it with a + "foo" because a could be a number.

lydell commented 8 years ago

You don't want to do it with a + "foo" because a could be a number.

1 + "foo" === "1foo"

eventualbuddha commented 8 years ago

True… so you'd just have to be careful that you don't do it when two non-strings could be added, like a + b + "c".

flying-sheep commented 8 years ago

well, that could be translated to

`${a + b}c`

algo idea:

  1. given a sequence of additions containing string literals
  2. collect the addition sequence of all leading non-string-literals and put them in a leading substitution if there are any (${})
  3. proceed as normal
a + b + "c" + d + e + "f" + g

is left-associative so the "c" + d + e is ("c" + d) + e.

juliankrispel commented 8 years ago

Honestly I'd like to preserve the code authors intention as much as possible. I thought about turning all string concatenation into template strings but I'm not convinced that it better serves peoples use-case or simplifies this problem.

The purpose of decaf is first and foremost not a code-improvement tool but a code-translation tool. I'd like to stick with the original intent here.

flying-sheep commented 8 years ago

sure. now that we can change the CS AST upstream, that’s also no longer a problem