| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index b16e3df6acb60c6b9aeba19b098dff4cf05f6368..9885456e2374c481efcb3a76f17dd9382abd98ef 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -221,6 +221,7 @@ class ParserBase : public Traits {
|
| bool is_generator() const { return IsGeneratorFunction(kind_); }
|
|
|
| FunctionKind kind() const { return kind_; }
|
| + FunctionState* outer() const { return outer_function_state_; }
|
|
|
| void set_generator_object_variable(
|
| typename Traits::Type::GeneratorVariable* variable) {
|
| @@ -253,7 +254,6 @@ class ParserBase : public Traits {
|
| // for generator functions to have this variable set.
|
| Variable* generator_object_variable_;
|
|
|
| -
|
| FunctionState** function_state_stack_;
|
| FunctionState* outer_function_state_;
|
| typename Traits::Type::Scope** scope_stack_;
|
| @@ -559,6 +559,7 @@ class ParserBase : public Traits {
|
| bool* ok);
|
| ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
|
| void AddTemplateExpression(ExpressionT);
|
| + ExpressionT ParseSuperExpression(bool is_new, 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,
|
| @@ -2709,8 +2710,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
|
| Consume(Token::NEW);
|
| int new_pos = position();
|
| ExpressionT result = this->EmptyExpression();
|
| - if (Check(Token::SUPER)) {
|
| - result = this->SuperReference(scope_, factory());
|
| + if (peek() == Token::SUPER) {
|
| + const bool is_new = true;
|
| + result = ParseSuperExpression(is_new, CHECK_OK);
|
| } else {
|
| result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
|
| }
|
| @@ -2767,21 +2769,8 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
|
| function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
|
| CHECK_OK);
|
| } else if (peek() == Token::SUPER) {
|
| - int beg_pos = position();
|
| - Consume(Token::SUPER);
|
| - Token::Value next = peek();
|
| - if (next == Token::PERIOD || next == Token::LBRACK) {
|
| - scope_->RecordSuperPropertyUsage();
|
| - result = this->SuperReference(scope_, factory());
|
| - } else if (next == Token::LPAREN) {
|
| - scope_->RecordSuperConstructorCallUsage();
|
| - result = this->SuperReference(scope_, factory());
|
| - } else {
|
| - ReportMessageAt(Scanner::Location(beg_pos, position()),
|
| - "unexpected_super");
|
| - *ok = false;
|
| - return this->EmptyExpression();
|
| - }
|
| + const bool is_new = false;
|
| + result = ParseSuperExpression(is_new, CHECK_OK);
|
| } else {
|
| result = ParsePrimaryExpression(CHECK_OK);
|
| }
|
| @@ -2793,6 +2782,39 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
|
|
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| +ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
|
| + int beg_pos = position();
|
| + Expect(Token::SUPER, CHECK_OK);
|
| +
|
| + FunctionState* function_state = function_state_;
|
| + while (IsArrowFunction(function_state->kind())) {
|
| + function_state = function_state->outer();
|
| + }
|
| + // TODO(arv): Handle eval scopes similarly.
|
| +
|
| + FunctionKind kind = function_state->kind();
|
| + if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
|
| + IsConstructor(kind)) {
|
| + if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
|
| + scope_->RecordSuperPropertyUsage();
|
| + return this->SuperReference(scope_, factory());
|
| + }
|
| + // new super() is never allowed.
|
| + // super() is only allowed in constructor
|
| + if (!is_new && peek() == Token::LPAREN && IsConstructor(kind)) {
|
| + scope_->RecordSuperConstructorCallUsage();
|
| + return this->SuperReference(scope_, factory());
|
| + }
|
| + }
|
| +
|
| + ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super");
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| +}
|
| +
|
| +
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
| bool* ok) {
|
| // Parses this part of MemberExpression:
|
|
|