| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 8d69b6e6f52c9fc72bc9bb3f235848ad7973a609..2e552e10f3b1256ab9b8bf6b0c87bd070900515e 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -366,6 +366,16 @@ bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
|
| }
|
|
|
|
|
| +bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
|
| + return identifier == parser_->ast_value_factory()->prototype_string();
|
| +}
|
| +
|
| +
|
| +bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
|
| + return identifier == parser_->ast_value_factory()->constructor_string();
|
| +}
|
| +
|
| +
|
| bool ParserTraits::IsThisProperty(Expression* expression) {
|
| DCHECK(expression != NULL);
|
| Property* property = expression->AsProperty();
|
| @@ -1136,6 +1146,8 @@ Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels,
|
| switch (peek()) {
|
| case Token::FUNCTION:
|
| return ParseFunctionDeclaration(NULL, ok);
|
| + case Token::CLASS:
|
| + return ParseClassDeclaration(NULL, ok);
|
| case Token::IMPORT:
|
| return ParseImportDeclaration(ok);
|
| case Token::EXPORT:
|
| @@ -1475,6 +1487,10 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
| result = ParseFunctionDeclaration(&names, CHECK_OK);
|
| break;
|
|
|
| + case Token::CLASS:
|
| + result = ParseClassDeclaration(&names, CHECK_OK);
|
| + break;
|
| +
|
| case Token::VAR:
|
| case Token::LET:
|
| case Token::CONST:
|
| @@ -1537,10 +1553,13 @@ Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels,
|
| // LetDeclaration
|
| // ConstDeclaration
|
| // GeneratorDeclaration
|
| + // ClassDeclaration
|
|
|
| switch (peek()) {
|
| case Token::FUNCTION:
|
| return ParseFunctionDeclaration(NULL, ok);
|
| + case Token::CLASS:
|
| + return ParseClassDeclaration(NULL, ok);
|
| case Token::CONST:
|
| return ParseVariableStatement(kModuleElement, NULL, ok);
|
| case Token::LET:
|
| @@ -1652,6 +1671,9 @@ Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
|
| return ParseFunctionDeclaration(NULL, ok);
|
| }
|
|
|
| + case Token::CLASS:
|
| + return ParseClassDeclaration(NULL, ok);
|
| +
|
| case Token::DEBUGGER:
|
| return ParseDebuggerStatement(ok);
|
|
|
| @@ -1920,6 +1942,47 @@ Statement* Parser::ParseFunctionDeclaration(
|
| }
|
|
|
|
|
| +Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
| + bool* ok) {
|
| + // ClassDeclaration ::
|
| + // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
|
| + //
|
| + // A ClassDeclaration
|
| + //
|
| + // class C { ... }
|
| + //
|
| + // has the same semantics as:
|
| + //
|
| + // let C = class C { ... };
|
| + //
|
| + // so rewrite it as such.
|
| +
|
| + Expect(Token::CLASS, CHECK_OK);
|
| + int pos = position();
|
| + bool is_strict_reserved = false;
|
| + const AstRawString* name =
|
| + ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
|
| + ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
|
| + is_strict_reserved, pos, CHECK_OK);
|
| +
|
| + Block* block = factory()->NewBlock(NULL, 1, true, pos);
|
| + VariableMode mode = LET;
|
| + VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
|
| + Declaration* declaration =
|
| + factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
|
| + Declare(declaration, true, CHECK_OK);
|
| +
|
| + Token::Value init_op = Token::INIT_LET;
|
| + Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
|
| + block->AddStatement(
|
| + factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
|
| + zone());
|
| +
|
| + if (names) names->Add(name, zone());
|
| + return block;
|
| +}
|
| +
|
| +
|
| Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
|
| if (allow_harmony_scoping() && strict_mode() == STRICT) {
|
| return ParseScopedBlock(labels, ok);
|
|
|