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

[[FIX]] Parse nested templates #2152

Closed
wants to merge 6 commits into from
Closed

Conversation

leebyron
Copy link
Contributor

@leebyron leebyron commented Feb 4, 2015

ES6 template literals are nestable, jshint's parser is capable, but it's lexer isn't. This patch adds the concept of a stack of contexts to the lexer, replacing the previous boolean flag. This context stack pattern is borrowed from the awesome Acorn parser project, where it's used to enable more than just template literals.

Fixes: #2151
Fixes: #2082
Fixes: #1814

ES6 template literals are nestable, jshint's parser is capable, but it's lexer isn't. This patch adds the concept of a stack of contexts to the lexer, replacing the previous boolean flag. This context stack pattern is borrowed from the awesome Acorn parser project, where it's used to enable more than just template literals.

Fixes: jshint#2151
@coveralls
Copy link

Coverage Status

Coverage increased (+0.0%) to 94.77% when pulling c874029 on leebyron:templatenest into 0ebe613 on jshint:master.

@leebyron
Copy link
Contributor Author

leebyron commented Feb 4, 2015

BTW, expanding the use of context can help solve #2082. Acorn uses the same approach to solve this problem.

Uses context introduced in previous diff to let lexer be contextually aware when parsing a "}" character.

Fixes: jshint#2082
@leebyron
Copy link
Contributor Author

leebyron commented Feb 4, 2015

Just also fixed #2082 in a 2nd commit in this patch, editing the description of the pull req now.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 94.75% when pulling f323327 on leebyron:templatenest into 0ebe613 on jshint:master.

tokenType = this.inTemplate ? Token.TemplateTail : Token.StringLiteral;
this.inTemplate = false;
// Final value is either StringLiteral or TemplateTail
tokenType = tokenType === Token.TemplateHead ? Token.StringLiteral : Token.TemplateTail;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you're fixing all this, you should also fix this: don't use Token.StringLiteral for no-substitution templates, otherwise they could be treated as valid directives, which is not true.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test case:

function fn() {
  `use strict`;
  return "\077";
} // should not yield any warnings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. I'll add that to this PR

@caitp
Copy link
Member

caitp commented Feb 4, 2015

rest of it lgtm, the other thing could be a followup bug

@leebyron
Copy link
Contributor Author

leebyron commented Feb 4, 2015

If you're comfortable merging before I get to fixing the directive issue, go nuts. I'll still follow up with that.

@caitp
Copy link
Member

caitp commented Feb 4, 2015

I think I will wait, I need to make sure the startLine thing can still work correctly with the stack structure, @jugglinmike or @rwaldron might also want to have a look

@leebyron
Copy link
Contributor Author

leebyron commented Feb 4, 2015

Just added your suggestion, @caitp. Let me know if that's in line with what you were looking for.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.04%) to 94.73% when pulling 61be438 on leebyron:templatenest into 0ebe613 on jshint:master.

@@ -31,7 +31,13 @@ var Token = {
RegExp: 9,
TemplateHead: 10,
TemplateMiddle: 11,
TemplateTail: 12
TemplateTail: 12,
TemplateString: 13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: NoSubstTemplate maybe?

Return a different kind of lexer token for full template strings such that they are not consumed by string directives.
@leebyron
Copy link
Contributor Author

leebyron commented Feb 5, 2015

Changed to NoSubstTemplate and added that second test.

I think the error is expected, you get the same error for this example:

function fn() {
  42;
}

So it's not specific to templates.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.04%) to 94.69% when pulling c402e25 on leebyron:templatenest into 13ae519 on jshint:master.

This is a slight alteration of jshint#2142 to cleanly rebase atop the previous diffs adding context, allowing it to work with nested templates.

Fixes: jshint#1814
@leebyron
Copy link
Contributor Author

leebyron commented Feb 5, 2015

@caitp - I just added another commit to this patch that covers what you were doing in #2142 but maintaining awareness of the context, so you won't need to rebase over this PR.

I took your test cases from that PR verbatim, but added cases for yield expressions as well.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 94.7% when pulling f76130c on leebyron:templatenest into 13ae519 on jshint:master.

@leebyron
Copy link
Contributor Author

leebyron commented Feb 6, 2015

Anything else you guys would like me to cover here @caitp @rwaldron?

@caitp
Copy link
Member

caitp commented Feb 6, 2015

good enough, can you try to figure out why coverage decreased? might need some extra test cases

@caitp
Copy link
Member

caitp commented Feb 6, 2015

I'm guessing it's probably for the yield multi-line expressions

@caitp
Copy link
Member

caitp commented Feb 6, 2015

hmm nope, I'm wrong about that :<

@caitp
Copy link
Member

caitp commented Feb 6, 2015

oh, you can remove the quotmark handling for backticks, since templates aren't string tokens anymore

@caitp
Copy link
Member

caitp commented Feb 6, 2015

missing a case for this as well

@leebyron
Copy link
Contributor Author

leebyron commented Feb 6, 2015

Good catch, I'll do that.

From looking at coverall's report, it's hard to tell what didn't get tested. It thinks coverage of style.js went down, but I didn't touch that file. Lex.js also went down but I can dig into that.

"}" should always yield a punctuator token, regardless of context.
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.0%) to 94.72% when pulling b3356dd on leebyron:templatenest into 13ae519 on jshint:master.

Remove quote key from template literal token.
@caitp
Copy link
Member

caitp commented Feb 6, 2015

Stuff in the last commit is okay, but I was referring to this << block is never hit because templates are not strings

@leebyron
Copy link
Contributor Author

leebyron commented Feb 6, 2015

I just saw that too, and updated that commit :)

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 94.75% when pulling cf7bc41 on leebyron:templatenest into 13ae519 on jshint:master.

@caitp
Copy link
Member

caitp commented Feb 6, 2015

coverage still seems to have gone down a tiny bit but I think everything relevant to this PR is covered... will merge

@caitp caitp closed this in 3da1eaf Feb 6, 2015
@leebyron
Copy link
Contributor Author

leebyron commented Feb 6, 2015

Thanks @caitp!

@leebyron leebyron deleted the templatenest branch February 6, 2015 18:48
jugglinmike pushed a commit to jugglinmike/jshint that referenced this pull request Feb 23, 2015
ES6 template literals are nestable, jshint's parser is capable, but it's lexer isn't. This patch adds the concept of a stack of contexts to the lexer, replacing the previous boolean flag. This context stack pattern is borrowed from the awesome Acorn parser project, where it's used to enable more than just template literals.

Closes jshint#2151
Closes jshint#2152
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support nested ES6 template literals Object Literals in String Templates show E020
3 participants