Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Unified Diff: src/parsing/parser-base.h

Issue 2665513002: [parser] Lift template literal invalid escape restriction (Closed)
Patch Set: address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 9809071d4789a58da84abfd32420688e0fd2a038..71e7f7412946eb843b5a5be4752cf990aab1e708 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -225,7 +225,8 @@ class ParserBase {
allow_harmony_trailing_commas_(false),
allow_harmony_class_fields_(false),
allow_harmony_object_rest_spread_(false),
- allow_harmony_dynamic_import_(false) {}
+ allow_harmony_dynamic_import_(false),
+ allow_harmony_template_escapes_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -240,6 +241,7 @@ class ParserBase {
ALLOW_ACCESSORS(harmony_class_fields);
ALLOW_ACCESSORS(harmony_object_rest_spread);
ALLOW_ACCESSORS(harmony_dynamic_import);
+ ALLOW_ACCESSORS(harmony_template_escapes);
#undef ALLOW_ACCESSORS
@@ -864,14 +866,12 @@ class ParserBase {
}
// Checks whether an octal literal was last seen between beg_pos and end_pos.
- // If so, reports an error. Only called for strict mode and template strings.
- void CheckOctalLiteral(int beg_pos, int end_pos, bool is_template, bool* ok) {
+ // Only called for strict mode strings.
+ void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
Scanner::Location octal = scanner()->octal_position();
if (octal.IsValid() && beg_pos <= octal.beg_pos &&
octal.end_pos <= end_pos) {
- MessageTemplate::Template message =
- is_template ? MessageTemplate::kTemplateOctalLiteral
- : scanner()->octal_message();
+ MessageTemplate::Template message = scanner()->octal_message();
DCHECK_NE(message, MessageTemplate::kNone);
impl()->ReportMessageAt(octal, message);
scanner()->clear_octal_position();
@@ -882,12 +882,35 @@ class ParserBase {
}
}
- inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- CheckOctalLiteral(beg_pos, end_pos, false, ok);
- }
-
- inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- CheckOctalLiteral(beg_pos, end_pos, true, ok);
+ // Checks if an octal literal or an invalid hex or unicode escape sequence
+ // appears between beg_pos and end_pos. In the presence of such, either
+ // returns false or reports an error, depending on dont_throw. Otherwise
+ // returns true.
+ inline bool CheckTemplateEscapes(int beg_pos, int end_pos, bool dont_throw,
+ bool* ok) {
+ Scanner::Location octal = scanner()->octal_position();
+ if (octal.IsValid() && beg_pos <= octal.beg_pos &&
+ octal.end_pos <= end_pos) {
+ if (dont_throw) {
+ scanner()->clear_octal_position();
+ return false;
+ }
+ MessageTemplate::Template message =
+ MessageTemplate::kTemplateOctalLiteral;
+ impl()->ReportMessageAt(octal, message);
+ scanner()->clear_octal_position();
+ *ok = false;
+ } else if (scanner()->has_invalid_template_escape()) {
+ if (dont_throw) {
+ scanner()->clear_invalid_template_escape();
+ return false;
+ }
+ impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
+ scanner()->invalid_template_escape_message());
+ scanner()->clear_invalid_template_escape();
+ *ok = false;
+ }
+ return true;
}
void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
@@ -1194,7 +1217,8 @@ class ParserBase {
Scanner::Location class_name_location,
bool name_is_strict_reserved,
int class_token_pos, bool* ok);
- ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
+ ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged,
+ bool* ok);
ExpressionT ParseSuperExpression(bool is_new, bool* ok);
ExpressionT ParseDynamicImportExpression(bool* ok);
ExpressionT ParseNewTargetExpression(bool* ok);
@@ -1503,6 +1527,7 @@ class ParserBase {
bool allow_harmony_class_fields_;
bool allow_harmony_object_rest_spread_;
bool allow_harmony_dynamic_import_;
+ bool allow_harmony_template_escapes_;
friend class DiscardableZoneScope;
};
@@ -1873,7 +1898,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
BindingPatternUnexpectedToken();
- return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok);
+ return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, false, ok);
case Token::MOD:
if (allow_natives() || extension_ != NULL) {
@@ -3294,7 +3319,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
impl()->RewriteNonPattern(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
- result = ParseTemplateLiteral(result, position(), CHECK_OK);
+ result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
break;
}
@@ -3569,7 +3594,7 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
expression->AsFunctionLiteral()->SetShouldEagerCompile();
}
}
- expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
+ expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK);
break;
}
case Token::ILLEGAL: {
@@ -4455,7 +4480,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
- ExpressionT tag, int start, bool* ok) {
+ ExpressionT tag, int start, bool tagged, bool* ok) {
// A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
// text followed by a substitution expression), finalized by a single
// TEMPLATE_TAIL.
@@ -4468,22 +4493,28 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
// TEMPLATE_SPAN, or a TEMPLATE_TAIL.
CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
+ bool allow_illegal_escapes = tagged && allow_harmony_template_escapes();
+ bool should_cook = true;
+
// If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
// In this case we may simply consume the token and build a template with a
// single TEMPLATE_SPAN and no expressions.
if (peek() == Token::TEMPLATE_TAIL) {
Consume(Token::TEMPLATE_TAIL);
int pos = position();
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
- impl()->AddTemplateSpan(&ts, true);
+ should_cook = CheckTemplateEscapes(pos, peek_position(),
+ allow_illegal_escapes, CHECK_OK);
+ impl()->AddTemplateSpan(&ts, should_cook, true);
return impl()->CloseTemplateLiteral(&ts, start, tag);
}
Consume(Token::TEMPLATE_SPAN);
int pos = position();
+ should_cook = CheckTemplateEscapes(pos, peek_position(),
+ allow_illegal_escapes, CHECK_OK);
typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
- impl()->AddTemplateSpan(&ts, false);
+ impl()->AddTemplateSpan(&ts, should_cook, false);
Token::Value next;
// If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
@@ -4491,7 +4522,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
// case, representing a TemplateMiddle).
do {
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
next = peek();
if (next == Token::EOS) {
impl()->ReportMessageAt(Scanner::Location(start, peek_position()),
@@ -4537,11 +4567,12 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
return impl()->EmptyExpression();
}
- impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
+ should_cook = CheckTemplateEscapes(pos, peek_position(),
+ allow_illegal_escapes, CHECK_OK);
+ impl()->AddTemplateSpan(&ts, should_cook, next == Token::TEMPLATE_TAIL);
} while (next == Token::TEMPLATE_SPAN);
DCHECK_EQ(next, Token::TEMPLATE_TAIL);
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
// Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
return impl()->CloseTemplateLiteral(&ts, start, tag);
}
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | src/parsing/scanner.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698