| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 41b3a31f0e1169068eaf2968fe55b67fc3904ee4..101409f1ba505b7ddd0fb3d561008ba78a39f08a 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -90,6 +90,7 @@ class ParserBase : public Traits {
|
| allow_harmony_sloppy_(false),
|
| allow_harmony_computed_property_names_(false),
|
| allow_harmony_rest_params_(false),
|
| + allow_harmony_new_target_(false),
|
| allow_strong_mode_(false) {}
|
|
|
| // Getters that indicate whether certain syntactical constructs are
|
| @@ -117,6 +118,7 @@ class ParserBase : public Traits {
|
| bool allow_harmony_rest_params() const {
|
| return allow_harmony_rest_params_;
|
| }
|
| + bool allow_harmony_new_target() const { return allow_harmony_new_target_; }
|
|
|
| bool allow_strong_mode() const { return allow_strong_mode_; }
|
|
|
| @@ -157,6 +159,9 @@ class ParserBase : public Traits {
|
| void set_allow_harmony_rest_params(bool allow) {
|
| allow_harmony_rest_params_ = allow;
|
| }
|
| + void set_allow_harmony_new_target(bool allow) {
|
| + allow_harmony_new_target_ = allow;
|
| + }
|
| void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
|
|
|
| protected:
|
| @@ -591,6 +596,7 @@ class ParserBase : public Traits {
|
| ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
| void AddTemplateExpression(ExpressionT);
|
| ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
| + ExpressionT ParseNewTargetExpression(bool* ok);
|
|
|
| // Checks if the expression is a valid reference expression (e.g., on the
|
| // left-hand side of assignments). Although ruled out by ECMA as early errors,
|
| @@ -686,6 +692,7 @@ class ParserBase : public Traits {
|
| bool allow_harmony_sloppy_;
|
| bool allow_harmony_computed_property_names_;
|
| bool allow_harmony_rest_params_;
|
| + bool allow_harmony_new_target_;
|
| bool allow_strong_mode_;
|
| };
|
|
|
| @@ -1397,6 +1404,11 @@ class PreParserTraits {
|
| return PreParserExpression::This();
|
| }
|
|
|
| + static PreParserExpression NewTargetExpression(Scope* scope,
|
| + PreParserFactory* factory) {
|
| + return PreParserExpression::Default();
|
| + }
|
| +
|
| static PreParserExpression SuperReference(Scope* scope,
|
| PreParserFactory* factory) {
|
| return PreParserExpression::Super();
|
| @@ -2678,6 +2690,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
|
| // NewExpression ::
|
| // ('new')+ MemberExpression
|
|
|
| + // NewTarget ::
|
| + // 'new' '.' 'target'
|
| +
|
| // The grammar for new expressions is pretty warped. We can have several 'new'
|
| // keywords following each other, and then a MemberExpression. When we see '('
|
| // after the MemberExpression, it's associated with the rightmost unassociated
|
| @@ -2699,6 +2714,8 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
|
| if (peek() == Token::SUPER) {
|
| const bool is_new = true;
|
| result = ParseSuperExpression(is_new, CHECK_OK);
|
| + } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
|
| + return ParseNewTargetExpression(CHECK_OK);
|
| } else {
|
| result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
|
| }
|
| @@ -2799,6 +2816,30 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
|
|
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| +ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
|
| + Consume(Token::PERIOD);
|
| + ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
|
| +
|
| + Scope* scope = scope_;
|
| + while (scope->is_eval_scope() || scope->is_arrow_scope()) {
|
| + scope = scope->outer_scope();
|
| + DCHECK_NOT_NULL(scope);
|
| + scope = scope->DeclarationScope();
|
| + }
|
| +
|
| + if (scope->is_script_scope() || scope->is_module_scope()) {
|
| + ReportMessageAt(scanner()->location(), "unexpected_new_target");
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| + }
|
| +
|
| + scope_->RecordNewTargetUsage();
|
| + return this->NewTargetExpression(scope_, factory());
|
| +}
|
| +
|
| +
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
| bool* ok) {
|
| // Parses this part of MemberExpression:
|
|
|