-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Conversation
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
ec9ea59
to
c874029
Compare
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
Just also fixed #2082 in a 2nd commit in this patch, editing the description of the pull req now. |
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
rest of it lgtm, the other thing could be a followup bug |
If you're comfortable merging before I get to fixing the directive issue, go nuts. I'll still follow up with that. |
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 |
Just added your suggestion, @caitp. Let me know if that's in line with what you were looking for. |
@@ -31,7 +31,13 @@ var Token = { | |||
RegExp: 9, | |||
TemplateHead: 10, | |||
TemplateMiddle: 11, | |||
TemplateTail: 12 | |||
TemplateTail: 12, | |||
TemplateString: 13 |
There was a problem hiding this comment.
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.
61be438
to
c402e25
Compare
Changed to I think the error is expected, you get the same error for this example: function fn() {
42;
} So it's not specific to templates. |
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
good enough, can you try to figure out why coverage decreased? might need some extra test cases |
I'm guessing it's probably for the |
hmm nope, I'm wrong about that :< |
oh, you can remove the quotmark handling for backticks, since templates aren't string tokens anymore |
missing a case for this as well |
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.
Remove quote key from template literal token.
b3356dd
to
cf7bc41
Compare
Stuff in the last commit is okay, but I was referring to this << block is never hit because templates are not strings |
I just saw that too, and updated that commit :) |
coverage still seems to have gone down a tiny bit but I think everything relevant to this PR is covered... will merge |
Thanks @caitp! |
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
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