Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ES6 Templates #960

Merged
merged 21 commits into from Oct 31, 2014
Merged

Support for ES6 Templates #960

merged 21 commits into from Oct 31, 2014

Conversation

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Oct 25, 2014

This pull request is meant to add support for ECMAScript 6 templates and address suggestion #13.

Right now this branch supports:

  • Both simple and substitution templates for all emit targets
  • Tagged template parse/emit solely for ES6 (and above) targets.
  • Syntactic highlighting in the LS for template literals
  • Completion lists in substitution position.

Things that will be done in a separate commit:

  • Type checking for tagged template expressions by checking assignability of substitution expressions to respective tag parameters.
  • Add typings for the "cooked strings" parameter of tags.
  • Patch up parts of the languages service that don't account for templates.
  • Better parse errors for places that expect string literals.
  • Experiment with brace matching on substitution templates.
  • Experiment with indentation in the language service.

Questions worth asking:

  • Do we want to accept simple (non-substitution) templates in places we accept string literals (i.e. module names, overloading on string constants, etc.)? On one hand, it would seem more consistent with the rest of our language, but ECMAScript 6 does not accept them in property names.
  • When indexing with a template literal, should we try to perform a static property lookup?
  • Are void-typed items allowed to be in substitution position? Are there any restrictions on what can be go in a substitution expression?
  • Do we want type arguments on a tagged template?
@@ -5932,6 +5939,12 @@ module ts {
return getUnionType([type1, type2]);
}

function checkTemplateExpression(node: TemplateExpression): void {
forEach((<TemplateExpression>node).templateSpans, templateSpan => {

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

Explain why this is correct. I believe it's because we rewrite this to string addition, and string addition allows the other side to be of any type. So we don't need to check for things like void types, etc. But it would be good to comment this bit.

}

function getTemplateLiteralAsStringLiteral(node: LiteralExpression): string {
return "\"" + escapeString(node.text) + "\"";

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

'"' +

}

function emitTemplateExpression(node: TemplateExpression): void {
if (compilerOptions.target >= ScriptTarget.ES6) {

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

Explain that in ES6 we don't need to do anything. But that in ES5 we'll convert things according. Explain the type of conversion you're trying to do.

}

var templateNeedsParens = isExpression(node.parent) &&
comparePrecedenceToBinaryPlus(node.parent) !== Comparison.LessThan;

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

explain this bit. (i understand it. but we should make the code clear).

// All unary operators have a higher precedence apart from yield.
// Arrow functions and conditionals have a lower precedence,
// although we convert the former into regular function expressions in ES5 mode,
// and in ES6 mode this function won't get called anyway.

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

add assert that you're in ES5 mode or lower.

* a literal component of a TemplateExpression.
*/
function scanTemplateAndSetTokenValue(): SyntaxKind {
var isStartOfTemplate = text.charCodeAt(pos) === CharacterCodes.backtick;

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

isTemplateHeadLiteral. Or: startedWithBacktick.

pos++;
var start = pos;
var contents = ""
var resultingToken = SyntaxKind.Unknown;

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

why ever set this here? Can 'unknown' actually be returned from here? If so, when?

case CharacterCodes.singleQuote:
return "\'";
case CharacterCodes.doubleQuote:
return "\"";

This comment has been minimized.

Copy link
@CyrusNajmabadi
return "\"";
case CharacterCodes.x:
case CharacterCodes.u:
var ch = scanHexDigits(ch === CharacterCodes.x ? 2 : 4, /*useExactCount*/ true);

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

mustMatchCount.

* Unconditionally back up and scan a template expression portion.
*/
function reScanTemplateToken(): SyntaxKind {
Debug.assert("'reScanTemplateToken' should only be called on a '}'");

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Oct 25, 2014

Contributor

you're asserting a string. This will always be true.

~~~~~~~~~~~~~~~~~~~~~~~~
`b`: 321
~~~~~~~
!!! error TS1159: Tagged templates are only available when targeting ECMAScript 6 and higher.

This comment has been minimized.

Copy link
@RyanCavanaugh

RyanCavanaugh Oct 25, 2014

Member

This error message isn't accurate/useful

@@ -5985,7 +5998,11 @@ module ts {
return booleanType;
case SyntaxKind.NumericLiteral:
return numberType;
case SyntaxKind.TemplateExpression:
checkTemplateExpression(<TemplateExpression>node);
// fall through

This comment has been minimized.

Copy link
@DickvdBrink

DickvdBrink Oct 25, 2014

Contributor

👍 for the "falls through" comment! Should be done on more places in the source code! :)

This comment has been minimized.

Copy link
@DanielRosenwasser

DanielRosenwasser Oct 27, 2014

Author Member

Thanks @DickvdBrink - I try to keep up that pattern in general. 😄

Although, I'm turning this into a straight return.

@JsonFreeman
Copy link
Contributor

JsonFreeman commented Oct 27, 2014

"Do we want to accept simple (non-substitution) templates in places we accept string literals (i.e. module names, overloading on string constants, etc.)? On one hand, it would seem more consistent with the rest of our language, but ECMAScript 6 does not accept them in property names."

I would say no. I'm not sure we have a reason to be more lenient than ES6.

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Oct 27, 2014

@JsonFreeman I agree; what about indexing?

@JsonFreeman
Copy link
Contributor

JsonFreeman commented Oct 27, 2014

I think we can type an index expression with literal, yes.

@JsonFreeman

This comment has been minimized.

Copy link
Contributor

JsonFreeman commented on src/compiler/types.ts in 518a5d3 Oct 28, 2014

Please put comments explaining what all these things are.

@JsonFreeman

This comment has been minimized.

Copy link
Contributor

JsonFreeman commented on src/compiler/emitter.ts in 518a5d3 Oct 28, 2014

If you factor out the meat of this function, you can use it for the "outside" case. You just need to pass in a precedence instead of an expression.

Conflicts:
	src/compiler/checker.ts
	src/services/services.ts
Conflicts:
	src/compiler/diagnosticInformationMap.generated.ts
	src/compiler/diagnosticMessages.json
	src/compiler/types.ts
	src/services/utilities.ts
@CyrusNajmabadi

This comment has been minimized.

Copy link
Contributor

CyrusNajmabadi commented on 4aafe1d Oct 31, 2014

👍

@CyrusNajmabadi

This comment has been minimized.

Copy link
Contributor

CyrusNajmabadi commented on 8786d30 Oct 31, 2014

👍

@CyrusNajmabadi

This comment has been minimized.

Copy link
Contributor

CyrusNajmabadi commented on d45fb77 Oct 31, 2014

👍

@CyrusNajmabadi

This comment has been minimized.

Copy link
Contributor

CyrusNajmabadi commented on aabfebd Oct 31, 2014

👍

@CyrusNajmabadi

This comment has been minimized.

Copy link
Contributor

CyrusNajmabadi commented on src/services/services.ts in ead3c1b Oct 31, 2014

StringOrRegularExpressionOrTemplateLiteral

DanielRosenwasser added a commit that referenced this pull request Oct 31, 2014
Support for ES6 Templates
@DanielRosenwasser DanielRosenwasser merged commit 0a97f5f into master Oct 31, 2014
1 check passed
1 check passed
continuous-integration/travis-ci The Travis CI build passed
Details
@DanielRosenwasser DanielRosenwasser deleted the templates branch Oct 31, 2014
@vvakame
Copy link
Contributor

vvakame commented Nov 10, 2014

@RyanCavanaugh excuse me. please add es6 label to this issue.
I want to check es6 feature on this url https://github.com/Microsoft/TypeScript/issues?q=label%3AES6

@danquirk danquirk added the ES6 label Nov 10, 2014
@Vadorequest
Copy link

Vadorequest commented Nov 19, 2014

I just noticed that this ES6 feature is still a proposal, so why implement it already? Not that it isn't great and useful, just wondering why focusing on things that are still status: Draft on ES6 specs. I guess you have your reasons, just wonder what they are ;)

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Nov 20, 2014

It's actually pretty much nailed down, and it's very unlikely that it will be removed/modified drastically. If anything does change, we'll be very mindful in addressing that. =)

@Vadorequest
Copy link

Vadorequest commented Nov 20, 2014

Ok, nice then, it's a nice feature btw, looking forward for 1.4. :)

@topherfangio
Copy link

topherfangio commented Dec 12, 2014

Hi there, I realize that this is on the Roadmap for 1.4. I'm curious though if we might see it sooner as perhaps an experimental option. My team and I would certainly love to start using this sooner rather than later to clean up our code :-)

Cheers!

@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Dec 12, 2014

Hey @topherfangio, glad to hear you're enthusiastic about this feature.

If you're dying to try it out, you can clone our repo and use our release-1.4 branch, but 1.4 is largely on the horizon, just be patient. =)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

9 participants
You can’t perform that action at this time.