summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing/parser-base.h
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2016-04-07 14:06:55 -0700
committerAli Ijaz Sheikh <ofrobots@google.com>2016-04-14 10:03:39 -0700
commit52af5c4eebf4de8638aef0338bd826656312a02a (patch)
tree628dc9fb0b558c3a73a2160706fef368876fe548 /deps/v8/src/parsing/parser-base.h
parent6e3e8acc7cc7ebd3d67db5ade1247b8b558efe09 (diff)
downloadandroid-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.tar.gz
android-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.tar.bz2
android-node-v8-52af5c4eebf4de8638aef0338bd826656312a02a.zip
deps: upgrade V8 to 5.0.71.32
* Pick up the branch head for V8 5.0 stable [1] * Edit v8 gitignore to allow trace_event copy * Update V8 DEP trace_event as per deps/v8/DEPS [2] [1] https://chromium.googlesource.com/v8/v8.git/+/3c67831 [2] https://chromium.googlesource.com/chromium/src/base/trace_event/common/+/4b09207e447ae5bd34643b4c6321bee7b76d35f9 Ref: https://github.com/nodejs/node/pull/5945 PR-URL: https://github.com/nodejs/node/pull/6111 Reviewed-By: targos - Michaƫl Zasso <mic.besace@gmail.com> Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r--deps/v8/src/parsing/parser-base.h552
1 files changed, 276 insertions, 276 deletions
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index d9da445977..6be19b397c 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -88,6 +88,7 @@ class ParserBase : public Traits {
typedef typename Traits::Type::Literal LiteralT;
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
typedef typename Traits::Type::StatementList StatementListT;
+ typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
@@ -116,7 +117,8 @@ class ParserBase : public Traits {
allow_strong_mode_(false),
allow_legacy_const_(true),
allow_harmony_do_expressions_(false),
- allow_harmony_function_name_(false) {}
+ allow_harmony_function_name_(false),
+ allow_harmony_function_sent_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -134,6 +136,7 @@ class ParserBase : public Traits {
ALLOW_ACCESSORS(legacy_const);
ALLOW_ACCESSORS(harmony_do_expressions);
ALLOW_ACCESSORS(harmony_function_name);
+ ALLOW_ACCESSORS(harmony_function_sent);
#undef ALLOW_ACCESSORS
uintptr_t stack_limit() const { return stack_limit_; }
@@ -242,11 +245,37 @@ class ParserBase : public Traits {
return destructuring_assignments_to_rewrite_;
}
+ List<ExpressionT>& expressions_in_tail_position() {
+ return expressions_in_tail_position_;
+ }
+ void AddExpressionInTailPosition(ExpressionT expression) {
+ if (collect_expressions_in_tail_position_) {
+ expressions_in_tail_position_.Add(expression);
+ }
+ }
+
+ bool collect_expressions_in_tail_position() const {
+ return collect_expressions_in_tail_position_;
+ }
+ void set_collect_expressions_in_tail_position(bool collect) {
+ collect_expressions_in_tail_position_ = collect;
+ }
+
+ ZoneList<ExpressionT>* non_patterns_to_rewrite() {
+ return &non_patterns_to_rewrite_;
+ }
+
+ private:
void AddDestructuringAssignment(DestructuringAssignment pair) {
destructuring_assignments_to_rewrite_.Add(pair);
}
- private:
+ V8_INLINE Scope* scope() { return *scope_stack_; }
+
+ void AddNonPatternForRewriting(ExpressionT expr) {
+ non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
+ }
+
// Used to assign an index to each literal that needs materialization in
// the function. Includes regexp literals, and boilerplate for object and
// array literals.
@@ -276,12 +305,14 @@ class ParserBase : public Traits {
Scope* outer_scope_;
List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
-
- void RewriteDestructuringAssignments();
+ List<ExpressionT> expressions_in_tail_position_;
+ bool collect_expressions_in_tail_position_;
+ ZoneList<ExpressionT> non_patterns_to_rewrite_;
typename Traits::Type::Factory* factory_;
friend class ParserTraits;
+ friend class PreParserTraits;
friend class Checkpoint;
};
@@ -436,6 +467,9 @@ class ParserBase : public Traits {
scanner()->is_next_contextual_keyword(keyword);
}
+ void ExpectMetaProperty(Vector<const char> property_name,
+ const char* full_name, int pos, bool* ok);
+
void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
Expect(Token::IDENTIFIER, ok);
if (!*ok) return;
@@ -461,6 +495,10 @@ class ParserBase : public Traits {
return false;
}
+ bool PeekInOrOf() {
+ return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
+ }
+
// 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,
@@ -563,8 +601,8 @@ class ParserBase : public Traits {
Scanner::Location location, Token::Value token,
MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
-
- void ReportClassifierError(const ExpressionClassifier::Error& error) {
+ void ReportClassifierError(
+ const typename ExpressionClassifier::Error& error) {
Traits::ReportMessageAt(error.location, error.message, error.arg,
error.type);
}
@@ -642,7 +680,7 @@ class ParserBase : public Traits {
// neither a valid binding pattern nor a valid parenthesized formal
// parameter list, show the "arrow formal parameters" error if the formals
// started with a parenthesis, and the binding pattern error otherwise.
- const ExpressionClassifier::Error& error =
+ const typename ExpressionClassifier::Error& error =
parenthesized_formals ? classifier->arrow_formal_parameters_error()
: classifier->binding_pattern_error();
ReportClassifierError(error);
@@ -715,10 +753,6 @@ class ParserBase : public Traits {
}
IdentifierT ParseIdentifierName(bool* ok);
- // Parses an identifier and determines whether or not it is 'get' or 'set'.
- IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
- bool* ok);
-
ExpressionT ParseRegExpLiteral(bool seen_equal,
ExpressionClassifier* classifier, bool* ok);
@@ -728,12 +762,9 @@ class ParserBase : public Traits {
ExpressionT ParseExpression(bool accept_IN, bool* ok);
ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
bool* ok);
- ExpressionT ParseExpression(bool accept_IN, int flags,
- ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
- bool* is_static, bool* is_computed_name,
- bool* is_identifier, bool* is_escaped_keyword,
+ bool* is_computed_name,
ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
ObjectLiteralPropertyT ParsePropertyDefinition(
@@ -744,21 +775,9 @@ class ParserBase : public Traits {
Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
bool* ok);
- enum AssignmentExpressionFlags {
- kIsNormalAssignment = 0,
- kIsPossiblePatternElement = 1 << 0,
- kIsPossibleArrowFormals = 1 << 1
- };
-
- ExpressionT ParseAssignmentExpression(bool accept_IN, int flags,
- ExpressionClassifier* classifier,
- bool* ok);
ExpressionT ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier,
- bool* ok) {
- return ParseAssignmentExpression(accept_IN, kIsNormalAssignment, classifier,
- ok);
- }
+ bool* ok);
ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier,
@@ -794,9 +813,9 @@ class ParserBase : public Traits {
ExpressionClassifier* classifier, bool* ok);
void ParseFormalParameterList(FormalParametersT* parameters,
ExpressionClassifier* classifier, bool* ok);
- void CheckArityRestrictions(
- int param_count, FunctionLiteral::ArityRestriction arity_restriction,
- bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
+ void CheckArityRestrictions(int param_count, FunctionKind function_type,
+ bool has_rest, int formals_start_pos,
+ int formals_end_pos, bool* ok);
bool IsNextLetKeyword();
@@ -829,6 +848,10 @@ class ParserBase : public Traits {
return true;
}
+ bool IsValidPattern(ExpressionT expression) {
+ return expression->IsObjectLiteral() || expression->IsArrayLiteral();
+ }
+
// Keep track of eval() calls since they disable all local variable
// optimizations. This checks if expression is an eval call, and if yes,
// forwards the information to scope.
@@ -932,9 +955,9 @@ class ParserBase : public Traits {
bool allow_legacy_const_;
bool allow_harmony_do_expressions_;
bool allow_harmony_function_name_;
+ bool allow_harmony_function_sent_;
};
-
template <class Traits>
ParserBase<Traits>::FunctionState::FunctionState(
FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
@@ -950,6 +973,8 @@ ParserBase<Traits>::FunctionState::FunctionState(
outer_function_state_(*function_state_stack),
scope_stack_(scope_stack),
outer_scope_(*scope_stack),
+ collect_expressions_in_tail_position_(true),
+ non_patterns_to_rewrite_(0, scope->zone()),
factory_(factory) {
*scope_stack_ = scope;
*function_state_stack = this;
@@ -967,7 +992,6 @@ template <class Traits>
void ParserBase<Traits>::GetUnexpectedTokenMessage(
Token::Value token, MessageTemplate::Template* message, const char** arg,
MessageTemplate::Template default_) {
- // Four of the tokens are treated specially
switch (token) {
case Token::EOS:
*message = MessageTemplate::kUnexpectedEOS;
@@ -1037,7 +1061,7 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt(
template <class Traits>
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
- ExpressionClassifier classifier;
+ ExpressionClassifier classifier(this);
auto result = ParseAndClassifyIdentifier(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
@@ -1091,10 +1115,8 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
scanner()->location(), MessageTemplate::kStrongUndefined);
if (is_strong(language_mode())) {
// TODO(dslomov): allow 'undefined' in nested patterns.
- classifier->RecordBindingPatternError(
- scanner()->location(), MessageTemplate::kStrongUndefined);
- classifier->RecordAssignmentPatternError(
- scanner()->location(), MessageTemplate::kStrongUndefined);
+ classifier->RecordPatternError(scanner()->location(),
+ MessageTemplate::kStrongUndefined);
}
}
@@ -1116,7 +1138,9 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
*ok = false;
return Traits::EmptyIdentifier();
}
- if (next == Token::LET) {
+ if (next == Token::LET ||
+ (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
+ scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
classifier->RecordLetPatternError(scanner()->location(),
MessageTemplate::kLetInLexicalBinding);
}
@@ -1172,18 +1196,6 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) {
template <class Traits>
-typename ParserBase<Traits>::IdentifierT
-ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
- bool* is_set,
- bool* ok) {
- IdentifierT result = ParseIdentifierName(ok);
- if (!*ok) return Traits::EmptyIdentifier();
- scanner()->IsGetOrSet(is_get, is_set);
- return result;
-}
-
-
-template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
int pos = peek_position();
@@ -1269,8 +1281,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
case Token::SMI:
case Token::NUMBER:
- classifier->RecordBindingPatternError(
- scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
+ BindingPatternUnexpectedToken(classifier);
return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
case Token::IDENTIFIER:
@@ -1286,8 +1297,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
}
case Token::STRING: {
- classifier->RecordBindingPatternError(
- scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
+ BindingPatternUnexpectedToken(classifier);
Consume(Token::STRING);
return this->ExpressionFromString(beg_pos, scanner(), factory());
}
@@ -1323,7 +1333,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
if (!classifier->is_valid_binding_pattern()) {
ArrowFormalParametersUnexpectedToken(classifier);
}
- BindingPatternUnexpectedToken(classifier);
+ classifier->RecordPatternError(scanner()->peek_location(),
+ MessageTemplate::kUnexpectedToken,
+ Token::String(Token::LPAREN));
Consume(Token::LPAREN);
if (Check(Token::RPAREN)) {
// ()=>x. The continuation that looks for the => is in
@@ -1331,20 +1343,23 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
classifier->RecordExpressionError(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(Token::RPAREN));
- classifier->RecordBindingPatternError(scanner()->location(),
- MessageTemplate::kUnexpectedToken,
- Token::String(Token::RPAREN));
return factory()->NewEmptyParentheses(beg_pos);
} else if (Check(Token::ELLIPSIS)) {
// (...x)=>x. The continuation that looks for the => is in
// ParseAssignmentExpression.
int ellipsis_pos = position();
+ int expr_pos = peek_position();
classifier->RecordExpressionError(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(Token::ELLIPSIS));
classifier->RecordNonSimpleParameter();
ExpressionT expr =
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
+ classifier->RecordArrowFormalParametersError(
+ Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidRestParameter);
+ }
if (peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest);
@@ -1352,17 +1367,13 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression();
}
Expect(Token::RPAREN, CHECK_OK);
- return factory()->NewSpread(expr, ellipsis_pos);
+ return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
}
// Heuristically try to detect immediately called functions before
// seeing the call parentheses.
parenthesized_function_ = (peek() == Token::FUNCTION);
- ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals,
- classifier, CHECK_OK);
+ ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- if (peek() != Token::ARROW) {
- expr->set_is_parenthesized();
- }
return expr;
}
@@ -1390,9 +1401,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
- classifier->RecordBindingPatternError(
- scanner()->peek_location(),
- MessageTemplate::kUnexpectedTemplateString);
+ BindingPatternUnexpectedToken(classifier);
return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
classifier, ok);
@@ -1423,9 +1432,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, bool* ok) {
- ExpressionClassifier classifier;
+ ExpressionClassifier classifier(this);
ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
- result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK);
+ Traits::RewriteNonPattern(&classifier, CHECK_OK);
return result;
}
@@ -1433,21 +1442,14 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
- return ParseExpression(accept_IN, kIsNormalAssignment, classifier, ok);
-}
-
-
-template <class Traits>
-typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
- bool accept_IN, int flags, ExpressionClassifier* classifier, bool* ok) {
// Expression ::
// AssignmentExpression
// Expression ',' AssignmentExpression
- ExpressionClassifier binding_classifier;
- ExpressionT result = this->ParseAssignmentExpression(
- accept_IN, flags, &binding_classifier, CHECK_OK);
- classifier->Accumulate(binding_classifier,
+ ExpressionClassifier binding_classifier(this);
+ ExpressionT result =
+ this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
+ classifier->Accumulate(&binding_classifier,
ExpressionClassifier::AllProductions);
bool is_simple_parameter_list = this->IsIdentifier(result);
bool seen_rest = false;
@@ -1469,14 +1471,21 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
Consume(Token::ELLIPSIS);
seen_rest = is_rest = true;
}
- int pos = position();
+ int pos = position(), expr_pos = peek_position();
ExpressionT right = this->ParseAssignmentExpression(
- accept_IN, flags, &binding_classifier, CHECK_OK);
- if (is_rest) right = factory()->NewSpread(right, pos);
+ accept_IN, &binding_classifier, CHECK_OK);
+ classifier->Accumulate(&binding_classifier,
+ ExpressionClassifier::AllProductions);
+ if (is_rest) {
+ if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
+ classifier->RecordArrowFormalParametersError(
+ Scanner::Location(pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidRestParameter);
+ }
+ right = factory()->NewSpread(right, pos, expr_pos);
+ }
is_simple_parameter_list =
is_simple_parameter_list && this->IsIdentifier(right);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
}
if (!is_simple_parameter_list || seen_rest) {
@@ -1511,9 +1520,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
} else if (peek() == Token::ELLIPSIS) {
int start_pos = peek_position();
Consume(Token::ELLIPSIS);
+ int expr_pos = peek_position();
ExpressionT argument =
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
- elem = factory()->NewSpread(argument, start_pos);
+ elem = factory()->NewSpread(argument, start_pos, expr_pos);
if (first_spread_index < 0) {
first_spread_index = values->length();
@@ -1534,8 +1544,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
MessageTemplate::kElementAfterRest);
}
} else {
- elem = this->ParseAssignmentExpression(true, kIsPossiblePatternElement,
- classifier, CHECK_OK);
+ int beg_pos = peek_position();
+ elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ CheckDestructuringElement(elem, classifier, beg_pos,
+ scanner()->location().end_pos);
}
values->Add(elem, zone_);
if (peek() != Token::RBRACK) {
@@ -1547,15 +1559,20 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
// Update the scope information before the pre-parsing bailout.
int literal_index = function_state_->NextMaterializedLiteralIndex();
- return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
- is_strong(language_mode()), pos);
+ ExpressionT result =
+ factory()->NewArrayLiteral(values, first_spread_index, literal_index,
+ is_strong(language_mode()), pos);
+ if (first_spread_index >= 0) {
+ result = factory()->NewRewritableExpression(result);
+ Traits::QueueNonPatternForRewriting(result);
+ }
+ return result;
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
- IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
- bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword,
+ IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
ExpressionClassifier* classifier, bool* ok) {
Token::Value token = peek();
int pos = peek_position();
@@ -1588,29 +1605,19 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
case Token::LBRACK: {
*is_computed_name = true;
Consume(Token::LBRACK);
- ExpressionClassifier computed_name_classifier;
+ ExpressionClassifier computed_name_classifier(this);
ExpressionT expression =
ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
- expression = Traits::RewriteNonPattern(
- expression, &computed_name_classifier, CHECK_OK);
- classifier->Accumulate(computed_name_classifier,
+ Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
+ classifier->Accumulate(&computed_name_classifier,
ExpressionClassifier::ExpressionProductions);
Expect(Token::RBRACK, CHECK_OK);
return expression;
}
- case Token::ESCAPED_KEYWORD:
- *is_escaped_keyword = true;
- *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
- break;
-
- case Token::STATIC:
- *is_static = true;
-
- // Fall through.
default:
- *is_identifier = true;
- *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
+ *name = ParseIdentifierName(CHECK_OK);
+ scanner()->IsGetOrSet(is_get, is_set);
break;
}
@@ -1631,27 +1638,19 @@ ParserBase<Traits>::ParsePropertyDefinition(
ExpressionT value = this->EmptyExpression();
bool is_get = false;
bool is_set = false;
- bool name_is_static = false;
bool is_generator = Check(Token::MUL);
Token::Value name_token = peek();
int next_beg_pos = scanner()->peek_location().beg_pos;
int next_end_pos = scanner()->peek_location().end_pos;
- bool is_identifier = false;
- bool is_escaped_keyword = false;
- ExpressionT name_expression = ParsePropertyName(
- name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier,
- &is_escaped_keyword, classifier,
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ ExpressionT name_expression =
+ ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
if (fni_ != nullptr && !*is_computed_name) {
this->PushLiteralName(fni_, *name);
}
- bool escaped_static =
- is_escaped_keyword &&
- scanner()->is_literal_contextual_keyword(CStrVector("static"));
-
if (!in_class && !is_generator) {
DCHECK(!is_static);
@@ -1663,15 +1662,18 @@ ParserBase<Traits>::ParsePropertyDefinition(
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
Consume(Token::COLON);
+ int beg_pos = peek_position();
value = this->ParseAssignmentExpression(
- true, kIsPossiblePatternElement, classifier,
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ CheckDestructuringElement(value, classifier, beg_pos,
+ scanner()->location().end_pos);
return factory()->NewObjectLiteralProperty(name_expression, value, false,
*is_computed_name);
}
- if ((is_identifier || is_escaped_keyword) &&
+ if (Token::IsIdentifier(name_token, language_mode(),
+ this->is_generator()) &&
(peek() == Token::COMMA || peek() == Token::RBRACE ||
peek() == Token::ASSIGN)) {
// PropertyDefinition
@@ -1680,14 +1682,6 @@ ParserBase<Traits>::ParsePropertyDefinition(
//
// CoverInitializedName
// IdentifierReference Initializer?
- if (!Token::IsIdentifier(name_token, language_mode(),
- this->is_generator())) {
- if (!escaped_static) {
- ReportUnexpectedTokenAt(scanner()->location(), name_token);
- *ok = false;
- return this->EmptyObjectLiteralProperty();
- }
- }
if (classifier->duplicate_finder() != nullptr &&
scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
classifier->RecordDuplicateFormalParameterError(scanner()->location());
@@ -1703,18 +1697,22 @@ ParserBase<Traits>::ParsePropertyDefinition(
if (peek() == Token::ASSIGN) {
Consume(Token::ASSIGN);
- ExpressionClassifier rhs_classifier;
+ ExpressionClassifier rhs_classifier(this);
ExpressionT rhs = this->ParseAssignmentExpression(
true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
- rhs = Traits::RewriteNonPattern(
- rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
- classifier->Accumulate(rhs_classifier,
+ Traits::RewriteNonPattern(&rhs_classifier,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ classifier->Accumulate(&rhs_classifier,
ExpressionClassifier::ExpressionProductions);
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
RelocInfo::kNoPosition);
classifier->RecordCoverInitializedNameError(
Scanner::Location(next_beg_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidCoverInitializedName);
+
+ if (allow_harmony_function_name()) {
+ Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
+ }
} else {
value = lhs;
}
@@ -1725,12 +1723,6 @@ ParserBase<Traits>::ParsePropertyDefinition(
}
}
- if (in_class && escaped_static && !is_static) {
- ReportUnexpectedTokenAt(scanner()->location(), name_token);
- *ok = false;
- return this->EmptyObjectLiteralProperty();
- }
-
// Method definitions are never valid in patterns.
classifier->RecordPatternError(
Scanner::Location(next_beg_pos, scanner()->location().end_pos),
@@ -1755,28 +1747,24 @@ ParserBase<Traits>::ParsePropertyDefinition(
: FunctionKind::kBaseConstructor;
}
- if (!in_class) kind = WithObjectLiteralBit(kind);
-
value = this->ParseFunctionLiteral(
*name, scanner()->location(), kSkipFunctionNameCheck, kind,
- RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression,
- FunctionLiteral::kNormalArity, language_mode(),
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
+ language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
return factory()->NewObjectLiteralProperty(name_expression, value,
ObjectLiteralProperty::COMPUTED,
is_static, *is_computed_name);
}
- if (in_class && name_is_static && !is_static) {
+ if (in_class && name_token == Token::STATIC && !is_static) {
// ClassElement (static)
// 'static' MethodDefinition
*name = this->EmptyIdentifier();
ObjectLiteralPropertyT property = ParsePropertyDefinition(
checker, true, has_extends, true, is_computed_name, nullptr, classifier,
name, ok);
- property = Traits::RewriteNonPatternObjectLiteralProperty(property,
- classifier, ok);
+ Traits::RewriteNonPattern(classifier, ok);
return property;
}
@@ -1789,8 +1777,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
name_token = peek();
name_expression = ParsePropertyName(
- name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care,
- &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ name, &dont_care, &dont_care, is_computed_name, classifier,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
if (!*is_computed_name) {
checker->CheckProperty(name_token, kAccessorProperty, is_static,
@@ -1798,12 +1786,10 @@ ParserBase<Traits>::ParsePropertyDefinition(
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
- FunctionKind kind = FunctionKind::kAccessorFunction;
- if (!in_class) kind = WithObjectLiteralBit(kind);
typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
- *name, scanner()->location(), kSkipFunctionNameCheck, kind,
- RelocInfo::kNoPosition, FunctionLiteral::kAnonymousExpression,
- is_get ? FunctionLiteral::kGetterArity : FunctionLiteral::kSetterArity,
+ *name, scanner()->location(), kSkipFunctionNameCheck,
+ is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
+ RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
// Make sure the name expression is a string since we need a Name for
@@ -1913,17 +1899,17 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
while (!done) {
int start_pos = peek_position();
bool is_spread = Check(Token::ELLIPSIS);
+ int expr_pos = peek_position();
ExpressionT argument = this->ParseAssignmentExpression(
true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
- argument = Traits::RewriteNonPattern(argument, classifier,
- CHECK_OK_CUSTOM(NullExpressionList));
+ Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
if (is_spread) {
if (!spread_arg.IsValid()) {
spread_arg.beg_pos = start_pos;
spread_arg.end_pos = peek_position();
}
- argument = factory()->NewSpread(argument, start_pos);
+ argument = factory()->NewSpread(argument, start_pos, expr_pos);
}
result->Add(argument, zone_);
@@ -1967,7 +1953,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
// Precedence = 2
template <class Traits>
typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
+ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier,
bool* ok) {
// AssignmentExpression ::
@@ -1975,8 +1961,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
// ArrowFunction
// YieldExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression
- bool maybe_pattern_element = flags & kIsPossiblePatternElement;
- bool maybe_arrow_formals = flags & kIsPossibleArrowFormals;
bool is_destructuring_assignment = false;
int lhs_beg_pos = peek_position();
@@ -1986,7 +1970,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
FuncNameInferrer::State fni_state(fni_);
ParserBase<Traits>::Checkpoint checkpoint(this);
- ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
+ ExpressionClassifier arrow_formals_classifier(this,
+ classifier->duplicate_finder());
bool parenthesized_formals = peek() == Token::LPAREN;
if (!parenthesized_formals) {
ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
@@ -1994,7 +1979,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
ExpressionT expression = this->ParseConditionalExpression(
accept_IN, &arrow_formals_classifier, CHECK_OK);
if (peek() == Token::ARROW) {
- BindingPatternUnexpectedToken(classifier);
+ classifier->RecordPatternError(scanner()->peek_location(),
+ MessageTemplate::kUnexpectedToken,
+ Token::String(Token::ARROW));
ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
parenthesized_formals, CHECK_OK);
Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
@@ -2022,11 +2009,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
}
expression = this->ParseArrowFunctionLiteral(
accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
- if (maybe_pattern_element) {
- classifier->RecordPatternError(
- Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
- MessageTemplate::kInvalidDestructuringTarget);
- }
if (fni_ != nullptr) fni_->Infer();
@@ -2039,44 +2021,42 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
// "expression" was not itself an arrow function parameter list, but it might
// form part of one. Propagate speculative formal parameter error locations.
+ // Do not merge pending non-pattern expressions yet!
classifier->Accumulate(
- arrow_formals_classifier,
+ &arrow_formals_classifier,
ExpressionClassifier::StandardProductions |
- ExpressionClassifier::FormalParametersProductions |
- ExpressionClassifier::CoverInitializedNameProduction);
-
- bool maybe_pattern =
- (expression->IsObjectLiteral() || expression->IsArrayLiteral()) &&
- !expression->is_parenthesized();
+ ExpressionClassifier::FormalParametersProductions |
+ ExpressionClassifier::CoverInitializedNameProduction,
+ false);
if (!Token::IsAssignmentOp(peek())) {
// Parsed conditional expression only (no assignment).
- if (maybe_pattern_element) {
- CheckDestructuringElement(expression, classifier, lhs_beg_pos,
- scanner()->location().end_pos);
- }
+ // Now pending non-pattern expressions must be merged.
+ classifier->MergeNonPatterns(&arrow_formals_classifier);
return expression;
}
+ // Now pending non-pattern expressions must be discarded.
+ arrow_formals_classifier.Discard();
+
if (!(allow_harmony_destructuring_bind() ||
allow_harmony_default_parameters())) {
BindingPatternUnexpectedToken(classifier);
}
- if (allow_harmony_destructuring_assignment() && maybe_pattern &&
+ if (allow_harmony_destructuring_assignment() && IsValidPattern(expression) &&
peek() == Token::ASSIGN) {
classifier->ForgiveCoverInitializedNameError();
ValidateAssignmentPattern(classifier, CHECK_OK);
is_destructuring_assignment = true;
- } else if (maybe_arrow_formals) {
+ } else if (allow_harmony_default_parameters() &&
+ !allow_harmony_destructuring_assignment()) {
+ // TODO(adamk): This branch should be removed once the destructuring
+ // assignment and default parameter flags are removed.
expression = this->ClassifyAndRewriteReferenceExpression(
classifier, expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInAssignment);
} else {
- if (maybe_pattern_element) {
- CheckDestructuringElement(expression, classifier, lhs_beg_pos,
- scanner()->location().end_pos);
- }
expression = this->CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
@@ -2086,20 +2066,20 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
Token::Value op = Next(); // Get assignment operator.
if (op != Token::ASSIGN) {
- classifier->RecordBindingPatternError(scanner()->location(),
- MessageTemplate::kUnexpectedToken,
- Token::String(op));
+ classifier->RecordPatternError(scanner()->location(),
+ MessageTemplate::kUnexpectedToken,
+ Token::String(op));
}
int pos = position();
- ExpressionClassifier rhs_classifier;
+ ExpressionClassifier rhs_classifier(this);
ExpressionT right =
this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
- right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK);
+ Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
classifier->Accumulate(
- rhs_classifier, ExpressionClassifier::ExpressionProductions |
- ExpressionClassifier::CoverInitializedNameProduction);
+ &rhs_classifier, ExpressionClassifier::ExpressionProductions |
+ ExpressionClassifier::CoverInitializedNameProduction);
// TODO(1231235): We try to estimate the set of properties set by
// constructors. We define a new property whenever there is an
@@ -2110,12 +2090,6 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
function_state_->AddProperty();
}
- if (op != Token::ASSIGN && maybe_pattern_element) {
- classifier->RecordAssignmentPatternError(
- Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
- MessageTemplate::kInvalidDestructuringTarget);
- }
-
this->CheckAssigningFunctionLiteralToProperty(expression, right);
if (fni_ != NULL) {
@@ -2137,7 +2111,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
if (is_destructuring_assignment) {
- result = factory()->NewRewritableAssignmentExpression(result);
+ result = factory()->NewRewritableExpression(result);
Traits::QueueDestructuringAssignmentForRewriting(result);
}
@@ -2179,16 +2153,12 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
// Delegating yields require an RHS; fall through.
default:
expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
- expression =
- Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
break;
}
}
if (kind == Yield::kDelegating) {
- // var iterator = subject[Symbol.iterator]();
- // Hackily disambiguate o from o.next and o [Symbol.iterator]().
- // TODO(verwaest): Come up with a better solution.
- expression = this->GetIterator(expression, factory(), pos + 1);
+ return Traits::RewriteYieldStar(generator_object, expression, pos);
}
// Hackily disambiguate o from o.next and o [Symbol.iterator]().
// TODO(verwaest): Come up with a better solution.
@@ -2213,7 +2183,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
ExpressionT expression =
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
if (peek() != Token::CONDITIONAL) return expression;
- expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
ArrowFormalParametersUnexpectedToken(classifier);
BindingPatternUnexpectedToken(classifier);
Consume(Token::CONDITIONAL);
@@ -2221,11 +2191,11 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
// expressions we always accept the 'in' keyword; see ECMA-262,
// section 11.12, page 58.
ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
- left = Traits::RewriteNonPattern(left, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
Expect(Token::COLON, CHECK_OK);
ExpressionT right =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
- right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
return factory()->NewConditional(expression, left, right, pos);
}
@@ -2241,7 +2211,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
// prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) {
- x = Traits::RewriteNonPattern(x, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Token::Value op = Next();
@@ -2249,7 +2219,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
int pos = position();
ExpressionT y =
ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
- y = Traits::RewriteNonPattern(y, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
factory())) {
@@ -2271,13 +2241,15 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
*ok = false;
return this->EmptyExpression();
+ } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
+ x = Traits::RewriteInstanceof(x, y, pos);
+ } else {
+ x = factory()->NewCompareOperation(cmp, x, y, pos);
+ if (cmp != op) {
+ // The comparison was negated - add a NOT.
+ x = factory()->NewUnaryOperation(Token::NOT, x, pos);
+ }
}
- x = factory()->NewCompareOperation(cmp, x, y, pos);
- if (cmp != op) {
- // The comparison was negated - add a NOT.
- x = factory()->NewUnaryOperation(Token::NOT, x, pos);
- }
-
} else {
// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
@@ -2312,7 +2284,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
op = Next();
int pos = position();
ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
- expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
if (op == Token::DELETE && is_strict(language_mode())) {
if (is_strong(language_mode())) {
@@ -2339,7 +2311,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
expression, beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
this->MarkExpressionAsAssigned(expression);
- expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
return factory()->NewCountOperation(op,
true /* prefix */,
@@ -2371,7 +2343,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
expression = this->MarkExpressionAsAssigned(expression);
- expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
Token::Value next = Next();
expression =
@@ -2397,19 +2369,20 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
while (true) {
switch (peek()) {
case Token::LBRACK: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
- index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
}
case Token::LPAREN: {
- result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
@@ -2473,6 +2446,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
}
case Token::PERIOD: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::PERIOD);
@@ -2486,6 +2460,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
@@ -2537,7 +2512,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
} else {
result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
}
- result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
if (peek() == Token::LPAREN) {
// NewExpression with arguments.
Scanner::Location spread_pos;
@@ -2584,6 +2559,23 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
Consume(Token::FUNCTION);
int function_token_position = position();
+
+ if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
+ // function.sent
+ int pos = position();
+ ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
+
+ if (!is_generator()) {
+ // TODO(neis): allow escaping into closures?
+ ReportMessageAt(scanner()->location(),
+ MessageTemplate::kUnexpectedFunctionSent);
+ *ok = false;
+ return this->EmptyExpression();
+ }
+
+ return this->FunctionSentExpression(scope_, factory(), pos);
+ }
+
bool is_generator = Check(Token::MUL);
IdentifierT name = this->EmptyIdentifier();
bool is_strict_reserved_name = false;
@@ -2602,8 +2594,7 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
: kFunctionNameValidityUnknown,
is_generator ? FunctionKind::kGeneratorFunction
: FunctionKind::kNormalFunction,
- function_token_position, function_type, FunctionLiteral::kNormalArity,
- language_mode(), CHECK_OK);
+ function_token_position, function_type, language_mode(), CHECK_OK);
} else if (peek() == Token::SUPER) {
const bool is_new = false;
result = ParseSuperExpression(is_new, classifier, CHECK_OK);
@@ -2637,7 +2628,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
- index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
left = factory()->NewProperty(this_expr, index, pos);
if (fni_ != NULL) {
this->PushPropertyName(fni_, index);
@@ -2673,7 +2664,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
ExpressionT right =
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
- right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
this->CheckAssigningFunctionLiteralToProperty(left, right);
function_state_->AddProperty();
if (fni_ != NULL) {
@@ -2796,13 +2787,26 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
return this->EmptyExpression();
}
+template <class Traits>
+void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
+ const char* full_name, int pos,
+ bool* ok) {
+ Consume(Token::PERIOD);
+ ExpectContextualKeyword(property_name, ok);
+ if (!*ok) return;
+ if (scanner()->literal_contains_escapes()) {
+ Traits::ReportMessageAt(
+ Scanner::Location(pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidEscapedMetaProperty, full_name);
+ *ok = false;
+ }
+}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
int pos = position();
- Consume(Token::PERIOD);
- ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
+ ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
if (!scope_->ReceiverScope()->is_function_scope()) {
ReportMessageAt(scanner()->location(),
@@ -2824,13 +2828,14 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
while (true) {
switch (peek()) {
case Token::LBRACK: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
- index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = factory()->NewProperty(expression, index, pos);
if (fni_ != NULL) {
this->PushPropertyName(fni_, index);
@@ -2839,6 +2844,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
break;
}
case Token::PERIOD: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
@@ -2854,6 +2860,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
}
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
int pos;
@@ -2908,14 +2915,19 @@ void ParserBase<Traits>::ParseFormalParameter(
ExpressionT initializer = Traits::EmptyExpression();
if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
- ExpressionClassifier init_classifier;
+ ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true, &init_classifier, ok);
if (!*ok) return;
- initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok);
+ Traits::RewriteNonPattern(&init_classifier, ok);
ValidateFormalParameterInitializer(&init_classifier, ok);
if (!*ok) return;
parameters->is_simple = false;
+ init_classifier.Discard();
classifier->RecordNonSimpleParameter();
+
+ if (allow_harmony_function_name()) {
+ Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
+ }
}
Traits::AddFormalParameter(parameters, pattern, initializer,
@@ -2972,33 +2984,29 @@ void ParserBase<Traits>::ParseFormalParameterList(
}
}
-
template <class Traits>
-void ParserBase<Traits>::CheckArityRestrictions(
- int param_count, FunctionLiteral::ArityRestriction arity_restriction,
- bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
- switch (arity_restriction) {
- case FunctionLiteral::kGetterArity:
- if (param_count != 0) {
- ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
- MessageTemplate::kBadGetterArity);
- *ok = false;
- }
- break;
- case FunctionLiteral::kSetterArity:
- if (param_count != 1) {
- ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
- MessageTemplate::kBadSetterArity);
- *ok = false;
- }
- if (has_rest) {
- ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
- MessageTemplate::kBadSetterRestParameter);
- *ok = false;
- }
- break;
- default:
- break;
+void ParserBase<Traits>::CheckArityRestrictions(int param_count,
+ FunctionKind function_kind,
+ bool has_rest,
+ int formals_start_pos,
+ int formals_end_pos, bool* ok) {
+ if (IsGetterFunction(function_kind)) {
+ if (param_count != 0) {
+ ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
+ MessageTemplate::kBadGetterArity);
+ *ok = false;
+ }
+ } else if (IsSetterFunction(function_kind)) {
+ if (param_count != 1) {
+ ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
+ MessageTemplate::kBadSetterArity);
+ *ok = false;
+ }
+ if (has_rest) {
+ ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
+ MessageTemplate::kBadSetterRestParameter);
+ *ok = false;
+ }
}
}
@@ -3082,10 +3090,10 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
// Single-expression body
int pos = position();
parenthesized_function_ = false;
- ExpressionClassifier classifier;
+ ExpressionClassifier classifier(this);
ExpressionT expression =
ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
- expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK);
+ Traits::RewriteNonPattern(&classifier, CHECK_OK);
body = this->NewStatementList(1, zone());
this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
body->Add(factory()->NewReturnStatement(expression, pos), zone());
@@ -3191,7 +3199,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
int expr_pos = peek_position();
ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
- expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
+ Traits::RewriteNonPattern(classifier, CHECK_OK);
Traits::AddTemplateExpression(&ts, expression);
if (peek() != Token::RBRACE) {
@@ -3245,7 +3253,7 @@ typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) {
- ExpressionClassifier classifier;
+ ExpressionClassifier classifier(this);
ExpressionT result = ClassifyAndRewriteReferenceExpression(
&classifier, expression, beg_pos, end_pos, message, type);
ValidateExpression(&classifier, ok);
@@ -3299,21 +3307,11 @@ template <typename Traits>
void ParserBase<Traits>::CheckDestructuringElement(
ExpressionT expression, ExpressionClassifier* classifier, int begin,
int end) {
- static const MessageTemplate::Template message =
- MessageTemplate::kInvalidDestructuringTarget;
- const Scanner::Location location(begin, end);
- if (expression->IsArrayLiteral() || expression->IsObjectLiteral() ||
- expression->IsAssignment()) {
- if (expression->is_parenthesized()) {
- classifier->RecordPatternError(location, message);
- }
- return;
- }
-
- if (expression->IsProperty()) {
- classifier->RecordBindingPatternError(location, message);
- } else if (!this->IsAssignableIdentifier(expression)) {
- classifier->RecordPatternError(location, message);
+ if (!IsValidPattern(expression) && !expression->IsAssignment() &&
+ !IsValidReferenceExpression(expression)) {
+ classifier->RecordAssignmentPatternError(
+ Scanner::Location(begin, end),
+ MessageTemplate::kInvalidDestructuringTarget);
}
}
@@ -3375,6 +3373,8 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
return;
}
}
+
+
} // namespace internal
} // namespace v8