| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 0643c3040a74dd25d8529cfd6f8a4102d0115a22..e768e8145591a95708721fe5fff6b275e977f8c7 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -114,6 +114,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_harmony_spreadcalls_(false),
|
| allow_strong_mode_(false) {}
|
|
|
| @@ -137,6 +138,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_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; }
|
|
|
| bool allow_strong_mode() const { return allow_strong_mode_; }
|
| @@ -169,6 +171,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_harmony_spreadcalls(bool allow) {
|
| allow_harmony_spreadcalls_ = allow;
|
| }
|
| @@ -627,6 +632,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);
|
|
|
| void ParseFormalParameter(FormalParameterScopeT* scope,
|
| FormalParameterErrorLocations* locs, bool is_rest,
|
| @@ -732,6 +738,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_harmony_spreadcalls_;
|
| bool allow_strong_mode_;
|
| };
|
| @@ -1505,6 +1512,13 @@ class PreParserTraits {
|
| return PreParserExpression::This();
|
| }
|
|
|
| + static PreParserExpression NewTargetExpression(Scope* scope,
|
| + PreParserFactory* factory,
|
| + int start_position,
|
| + int end_position) {
|
| + return PreParserExpression::Default();
|
| + }
|
| +
|
| static PreParserExpression SuperReference(Scope* scope,
|
| PreParserFactory* factory) {
|
| return PreParserExpression::Default();
|
| @@ -2908,6 +2922,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
|
| @@ -2929,6 +2946,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);
|
| }
|
| @@ -3036,6 +3055,7 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
|
| return this->EmptyExpression();
|
| }
|
| }
|
| + scope_->RecordNewTargetUsage();
|
| function_state->set_super_call_location(scanner()->location());
|
| return this->SuperReference(scope_, factory());
|
| }
|
| @@ -3049,6 +3069,48 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
|
|
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| +ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
|
| + int pos = position();
|
| + Consume(Token::PERIOD);
|
| + ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
|
| +
|
| + Scope* scope = scope_->DeclarationScope();
|
| + 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();
|
| +
|
| + // ExpressionT is_construct_call = factory()->NewCallRuntime(
|
| + // ast_value_factory()->is_construct_call_string(),
|
| + // Runtime::FunctionForId(Runtime::kInlineIsConstructCall),
|
| + // this->NewExpressionList(0, zone_), RelocInfo::kNoPosition);
|
| +
|
| + // ExpressionT void_zero = factory()->NewUnaryOperation(
|
| + // Token::VOID, factory()->NewNumberLiteral(0, RelocInfo::kNoPosition),
|
| + // RelocInfo::kNoPosition);
|
| +
|
| + // %_IsConstructCall() ? new.target : void 0
|
| + // return factory()->NewConditional(
|
| + // is_construct_call,
|
| + // this->NewTargetExpression(scope_, factory(), pos, position()),
|
| + // void_zero,
|
| + // RelocInfo::kNoPosition);
|
| +
|
| + return this->NewTargetExpression(scope_, factory(), pos, position());
|
| +}
|
| +
|
| +
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
| bool* ok) {
|
| // Parses this part of MemberExpression:
|
|
|