Implement ES6 Template Literals

RESOLVED DUPLICATE of bug 1038259

Status

()

RESOLVED DUPLICATE of bug 1038259
8 years ago
5 years ago

People

(Reporter: brendan, Unassigned)

Tracking

(Blocks: 1 bug, {dev-doc-complete, feature})

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [js:p2], URL)

Attachments

(1 attachment)

(Reporter)

Description

8 years ago
Should be fun. Who will take?

/be

Comment 1

8 years ago
I tried to follow the Mozilla C++ style guide, but this is my first
time mucking around with Mozilla code so apologies in advance.

I'm trying to implement quasiliterals in SpiderMonkey :
http://wiki.ecmascript.org/doku.php?id=harmony:quasis

Instead of implementing the full desugaring in one go, this is a rough
draft that just desugars
    foo`bar${baz}boo`
to
    foo(['bar', 'boo'], [baz])
and
    `foo${bar}baz`
to
    defaultQuasi(['foo', 'baz'], [bar])

The full desugaring requires hoisting a variable declaration along
with its initializer, though the name should only be used at the
quasi usage site so need not be implemented as a declaration.
Is there any other code in jsparse.cpp that hoists declarations?
I found js::AtomDecls::addHoist and JSOP_DEFCONST which somehow
interacts with js_DefineCompileTimeConstant, but I'm not clear on
which mechanism is applicable here.

Where are good places to put tests?  I define a few error messages but
am unclear where I should test failures to parse/lex.

Where do value tests go?
I haven't read the code yet but one thing to be aware of is that extending the syntax always requires two additional considerations:

(1) Reflect.parse: the parser API, implemented in jsreflect.{h,cpp}, should be extended to recognize the new syntax

(2) the decompiler: we throw away source code, so Function.prototype.toString() is implemented by decompiling from bytecode back to JS source.

Given (2), desugaring isn't always the best option, since it will decompile to the desugared code rather than something closer to the original source.

Dave
We also don't have a mechanism to desugar to a referentially transparent variable reference like defaultQuasi, which is another concern about desugaring.

Dave

Comment 4

8 years ago
Hmm.  For 2, how does the decompiler handle the distinction between the referentially transparent /./ and the non-transparent new RegExp('.')?  Different node types?  If so, I guess I would need to have some way to distinguish in jsemitted code between a quasi and a non-quasi.

I'll look into the jsreflect stuff.
> Hmm.  For 2, how does the decompiler handle the distinction between the
> referentially transparent /./ and the non-transparent new RegExp('.')? 
> Different node types?

Yep, different node types -- TOK_REGEXP vs TOK_NEW, I believe:

    http://mxr.mozilla.org/mozilla-central/source/js/src/frontend/ParseNode.h#211
    http://mxr.mozilla.org/mozilla-central/source/js/src/frontend/ParseNode.h#183

and they compile to different opcodes -- JSOP_REGEXP vs JSOP_NEWOBJECT, I think?

    http://mxr.mozilla.org/mozilla-central/source/js/src/jsopcode.tbl#257
    http://mxr.mozilla.org/mozilla-central/source/js/src/jsopcode.tbl#423

> If so, I guess I would need to have some way to distinguish in jsemitted
> code between a quasi and a non-quasi.

Yes, it would either entail some sort of JSOP_QUASI or perhaps source hints? I don't know how source hints work. (Brendan may be the best person to help you there.) Feel free to pop over to #jsapi on irc.mozilla.org -- that's usually the best place to get help with the SpiderMonkey codebase.

> I'll look into the jsreflect stuff.

That could be a good place to learn the structure of the AST; it's a pretty straightforward recursive descent. I was forced to learn our weird JSParseNode data structure when I wrote jsreflect. :)

Dave
Blocks: 694100
FYI: If you need some basic test cases, feel free to use the ones I've written for bug 783507, see https://github.com/anba/rhino/commit/77cbdbbe673670b4b4fe781b925d6f3471354eff

Comment 7

7 years ago
they are now called template strings. we should rename the bug and change the code accordingly to avoid confusion.

also i hope this will be ready soon: without e4x (which is going to be removed), there are no multiline strings.

Comment 8

7 years ago
(In reply to flying sheep from comment #7)
> also i hope this will be ready soon: without e4x (which is going to be
> removed), there are no multiline strings.
ES5 introduced multiline strings. You need to escape a line feed inside the string with a backslash ('\'). I think it's widely supported (it works on Firefox at least, I've just tested).
Summary: Implement ES.next quasi-literals → Implement Harmony template strings

Comment 9

7 years ago
that’s no multiline string, that’s a sting literal with escaped newlines. and when you escape newlines, they aren’t there anymore, so instead of

var templ = `first line
second line`;

one has to write

var string = "first line\n\
second line";

that gets tedious fast, adds visual noise, and is a error source (if the lines are ragged, one can’t easily spot a missing "\n\").

of course in simple cases like this example, it’s OK to use normal strings, but as soon as you have more than a few lines, one needs a simpler alternative.

Comment 10

7 years ago
PS for everyone who didn’t know it: wit E4X, one could do that:

var multiline = "" + <r><![CDATA[
first line
second line
]]></r>;

that was almost as easy as template strings for usage as multiline strings.
Summary: Implement Harmony template strings → Implement ES6 Template Literals

Comment 11

6 years ago
Would it be worth it to implement a version of this that allows for multiline strings without implementing the full template literal stuff? I think the backticks to allow multiline strings will provide **a lot** of benefit to JS devs, and that might be an easier task and step than implementing all of the sugar. Currently I've seen folks either doing lots of string concats, or lots of \n\, or lots of sticking their strings in HTML script text tags. Would be nice to have ML string support in.
(In reply to breck7 from comment #11)
> Would it be worth it to implement a version of this that allows for
> multiline strings without implementing the full template literal stuff? 

If you asking about how to approach a phased implementation of template strings I'd suggest starting with 
implementing TemplateLiteral  http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literals 

Those are template strings without the tag function and the associated call semantics.  They just do literal substitutions. I don't see much point in not going at least that far as the first phase of an implementation.
From platform l10n standpoint, template literals are very low value. They're supposed to help with l10n, but we'll not be using them. We'll be investigating messageFormat and L20n (or some blend of those two).
Template Strings have a lot of use cases relating to both string interpolation and skupporting internal DSLs. But l10n isn't their primary motivation or even a very strong use case for them.
Keywords: dev-doc-needed
(In reply to Zbigniew Braniecki [:gandalf] from comment #13)
> From platform l10n standpoint, template literals are very low value. They're
> supposed to help with l10n, but we'll not be using them. 

Perhaps you should elaborate on this in a post to es-discuss? It's not productive to post to bug a thread that can do nothing to help. https://mail.mozilla.org/listinfo/es-discuss
(In reply to Rick Waldron [:rwaldron] from comment #15)
> Perhaps you should elaborate on this in a post to es-discuss? It's not
> productive to post to bug a thread that can do nothing to help.
> https://mail.mozilla.org/listinfo/es-discuss

My only goal was to provide information to the bug owner on wherever this technology will be useful for l10n purposes. Allen in Comment 14 explained that template literals are not intended for l10n, and pointed at the use cases.
What do you want me to elaborate on at es-discuss?

Comment 17

6 years ago
the point is still that the most basic form of this allows *multiline strings*

let’s just implement “backtick opens and closes string literals that can span multiple lines”, and one great annoyance of JS is alleviated.
Keywords: feature
Whiteboard: [js:p2]

Updated

5 years ago
Depends on: 1021368

Updated

5 years ago
Depends on: 1024748

Comment 18

5 years ago
Is there anything left to do here? Is this already enabled by default? If not, is there a bug for enabling template literals?
relnote-firefox: --- → ?
Jason: is this meta bug complete now that bug 1021368 ("Implement NoSubstitutionTemplate as described in ES6 draft 11.8.6") landed?
Flags: needinfo?(jorendorff)
No, there are still tagged templates left to do.
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tagged-templates

It isn't filed yet. Soon.
Flags: needinfo?(jorendorff)

Comment 21

5 years ago
I’m confused: Aren’t tagged templates one more step further?

“there are still tagged templates left to do” implies that everything before that is done, but how I see it, there’s:

1. NoSubstitutionTemplate: `foobarbaz`
2. Template: `foo${bar}baz`
3. Tagged Template: taggo`foo${bar}baz`

The 1st is basically a multiline-enabled string.
The 2nd is the above, but evaluates and substitutes expressions inside ${}
The 3rd calls a function on the parts and a raw version of the input basically like this: taggo(['foo', 'baz'], bar)

Am I right that bug 1021368 only implemented the 1st very basic one, or is the 2nd also done already?
Only tagged templates still need to be implemented.

1. NoSubstitutionTemplate: bug 1021368
2. Template: bug 1024748
3. Tagged Template: bug 1031397

Updated

5 years ago
Depends on: 1031397
OK, this is the meta bug for templates. Once bug 1031397 lands, there's still one more thing to do here: flip the switch so that templates are no longer nightly-only.

(Then, after we branch for FF33, we should remove the #ifdefs entirely and change the tests to not use the weird function.toString() trick. But that's a follow-up bug.)

Comment 24

5 years ago
i think we should flip the switch even if tagged templates aren’t ready for FF33. untagged ones (and even NoSubstitutionTemplates) are too useful to miss longer than absolutely necessary!

(multiline strings are one of the things whose lack is very hard to circumvent since E4X is gone. function() {/*Comment*/}.toString() is just ugly and hacky)
We branched 33. What are your plans here? Thanks.
Flags: needinfo?(jorendorff)
Assignee: general → nobody
(In reply to Sylvestre Ledru [:sylvestre] from comment #25)
> We branched 33. What are your plans here? Thanks.

Template strings didn't make 33. Since they are #ifdef'd to be nightly-only, they are not in FF33 builds at all.

Guptha is continuing to make progress on tagged templates and we plan to enable templates in FF34.
Flags: needinfo?(jorendorff)

Updated

5 years ago
Depends on: 1038259
DUPing forward. This is done.
Status: NEW → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1038259
Already relnoted in bug 1038259
relnote-firefox: ? → ---
You need to log in before you can comment on or make changes to this bug.