Commit 7efd2eb1 authored by arv@chromium.org's avatar arv@chromium.org

Class syntax parsing

This implements parsing for ClassExpression and ClassDeclaration.
The runtime is not yet implemented and the value is currently
hard coded to undefined.

BUG=v8:3330
LOG=Y
R=dslomov@chromium.org, marja@chromium.org, rossberg@chromium.org

Review URL: https://codereview.chromium.org/561913002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23988 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7062b8fb
......@@ -235,32 +235,33 @@ class AstValue : public ZoneObject {
// For generating string constants.
#define STRING_CONSTANTS(F) \
F(anonymous_function, "(anonymous function)") \
F(arguments, "arguments") \
F(done, "done") \
F(dot, ".") \
F(dot_for, ".for") \
F(dot_generator, ".generator") \
F(dot_generator_object, ".generator_object") \
F(dot_iterator, ".iterator") \
F(dot_module, ".module") \
F(dot_result, ".result") \
F(empty, "") \
F(eval, "eval") \
#define STRING_CONSTANTS(F) \
F(anonymous_function, "(anonymous function)") \
F(arguments, "arguments") \
F(constructor, "constructor") \
F(done, "done") \
F(dot, ".") \
F(dot_for, ".for") \
F(dot_generator, ".generator") \
F(dot_generator_object, ".generator_object") \
F(dot_iterator, ".iterator") \
F(dot_module, ".module") \
F(dot_result, ".result") \
F(empty, "") \
F(eval, "eval") \
F(initialize_const_global, "initializeConstGlobal") \
F(initialize_var_global, "initializeVarGlobal") \
F(make_reference_error, "MakeReferenceError") \
F(make_syntax_error, "MakeSyntaxError") \
F(make_type_error, "MakeTypeError") \
F(module, "module") \
F(native, "native") \
F(next, "next") \
F(proto, "__proto__") \
F(prototype, "prototype") \
F(this, "this") \
F(use_asm, "use asm") \
F(use_strict, "use strict") \
F(initialize_var_global, "initializeVarGlobal") \
F(make_reference_error, "MakeReferenceError") \
F(make_syntax_error, "MakeSyntaxError") \
F(make_type_error, "MakeTypeError") \
F(module, "module") \
F(native, "native") \
F(next, "next") \
F(proto, "__proto__") \
F(prototype, "prototype") \
F(this, "this") \
F(use_asm, "use asm") \
F(use_strict, "use strict") \
F(value, "value")
......
......@@ -173,10 +173,12 @@ void FunctionLiteral::InitializeSharedInfo(
ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone,
AstValueFactory* ast_value_factory,
Literal* key, Expression* value) {
Literal* key, Expression* value,
bool is_static) {
emit_store_ = true;
key_ = key;
value_ = value;
is_static_ = is_static;
if (key->raw_value()->EqualsString(ast_value_factory->proto_string())) {
kind_ = PROTOTYPE;
} else if (value_->AsMaterializedLiteral() != NULL) {
......@@ -189,11 +191,13 @@ ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone,
}
ObjectLiteralProperty::ObjectLiteralProperty(
Zone* zone, bool is_getter, FunctionLiteral* value) {
ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone, bool is_getter,
FunctionLiteral* value,
bool is_static) {
emit_store_ = true;
value_ = value;
kind_ = is_getter ? GETTER : SETTER;
is_static_ = is_static;
}
......@@ -1090,6 +1094,7 @@ DONT_OPTIMIZE_NODE(ModuleUrl)
DONT_OPTIMIZE_NODE(ModuleStatement)
DONT_OPTIMIZE_NODE(WithStatement)
DONT_OPTIMIZE_NODE(DebuggerStatement)
DONT_OPTIMIZE_NODE(ClassLiteral)
DONT_OPTIMIZE_NODE(NativeFunctionLiteral)
DONT_OPTIMIZE_NODE(SuperReference)
......
......@@ -40,12 +40,12 @@ namespace internal {
// Nodes of the abstract syntax tree. Only concrete classes are
// enumerated here.
#define DECLARATION_NODE_LIST(V) \
V(VariableDeclaration) \
V(FunctionDeclaration) \
V(ModuleDeclaration) \
V(ImportDeclaration) \
V(ExportDeclaration) \
#define DECLARATION_NODE_LIST(V) \
V(VariableDeclaration) \
V(FunctionDeclaration) \
V(ModuleDeclaration) \
V(ImportDeclaration) \
V(ExportDeclaration)
#define MODULE_NODE_LIST(V) \
V(ModuleLiteral) \
......@@ -73,28 +73,29 @@ namespace internal {
V(TryFinallyStatement) \
V(DebuggerStatement)
#define EXPRESSION_NODE_LIST(V) \
V(FunctionLiteral) \
V(NativeFunctionLiteral) \
V(Conditional) \
V(VariableProxy) \
V(Literal) \
V(RegExpLiteral) \
V(ObjectLiteral) \
V(ArrayLiteral) \
V(Assignment) \
V(Yield) \
V(Throw) \
V(Property) \
V(Call) \
V(CallNew) \
V(CallRuntime) \
V(UnaryOperation) \
V(CountOperation) \
V(BinaryOperation) \
V(CompareOperation) \
V(ThisFunction) \
V(SuperReference) \
#define EXPRESSION_NODE_LIST(V) \
V(FunctionLiteral) \
V(ClassLiteral) \
V(NativeFunctionLiteral) \
V(Conditional) \
V(VariableProxy) \
V(Literal) \
V(RegExpLiteral) \
V(ObjectLiteral) \
V(ArrayLiteral) \
V(Assignment) \
V(Yield) \
V(Throw) \
V(Property) \
V(Call) \
V(CallNew) \
V(CallRuntime) \
V(UnaryOperation) \
V(CountOperation) \
V(BinaryOperation) \
V(CompareOperation) \
V(ThisFunction) \
V(SuperReference) \
V(CaseClause)
#define AST_NODE_LIST(V) \
......@@ -1459,7 +1460,7 @@ class ObjectLiteralProperty FINAL : public ZoneObject {
};
ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory,
Literal* key, Expression* value);
Literal* key, Expression* value, bool is_static);
Literal* key() { return key_; }
Expression* value() { return value_; }
......@@ -1478,7 +1479,8 @@ class ObjectLiteralProperty FINAL : public ZoneObject {
protected:
template<class> friend class AstNodeFactory;
ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value);
ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value,
bool is_static);
void set_key(Literal* key) { key_ = key; }
private:
......@@ -1486,6 +1488,7 @@ class ObjectLiteralProperty FINAL : public ZoneObject {
Expression* value_;
Kind kind_;
bool emit_store_;
bool is_static_;
Handle<Map> receiver_type_;
};
......@@ -2498,6 +2501,40 @@ class FunctionLiteral FINAL : public Expression {
};
class ClassLiteral FINAL : public Expression {
public:
typedef ObjectLiteralProperty Property;
DECLARE_NODE_TYPE(ClassLiteral)
Handle<String> name() const { return raw_name_->string(); }
const AstRawString* raw_name() const { return raw_name_; }
Expression* extends() const { return extends_; }
FunctionLiteral* constructor() const { return constructor_; }
ZoneList<Property*>* properties() const { return properties_; }
protected:
ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
FunctionLiteral* constructor, ZoneList<Property*>* properties,
AstValueFactory* ast_value_factory, int position, IdGen* id_gen)
: Expression(zone, position, id_gen),
raw_name_(name),
raw_inferred_name_(ast_value_factory->empty_string()),
extends_(extends),
constructor_(constructor),
properties_(properties) {}
private:
const AstRawString* raw_name_;
Handle<String> name_;
const AstString* raw_inferred_name_;
Handle<String> inferred_name_;
Expression* extends_;
FunctionLiteral* constructor_;
ZoneList<Property*>* properties_;
};
class NativeFunctionLiteral FINAL : public Expression {
public:
DECLARE_NODE_TYPE(NativeFunctionLiteral)
......@@ -3300,16 +3337,17 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
}
ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key,
Expression* value) {
return new (zone_)
ObjectLiteral::Property(zone_, ast_value_factory_, key, value);
Expression* value,
bool is_static) {
return new (zone_) ObjectLiteral::Property(zone_, ast_value_factory_, key,
value, is_static);
}
ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
FunctionLiteral* value,
int pos) {
int pos, bool is_static) {
ObjectLiteral::Property* prop =
new(zone_) ObjectLiteral::Property(zone_, is_getter, value);
new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static);
prop->set_key(NewStringLiteral(value->raw_name(), pos));
return prop; // Not an AST node, will not be visited.
}
......@@ -3465,6 +3503,17 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
return lit;
}
ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends,
FunctionLiteral* constructor,
ZoneList<ObjectLiteral::Property*>* properties,
AstValueFactory* ast_value_factory,
int position) {
ClassLiteral* lit =
new (zone_) ClassLiteral(zone_, name, extends, constructor, properties,
ast_value_factory, position, id_gen_);
VISIT_AND_RETURN(ClassLiteral, lit)
}
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
v8::Extension* extension,
int pos) {
......
......@@ -812,6 +812,12 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
// TODO(arv): Implement.
UNREACHABLE();
}
void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
UNREACHABLE();
}
......
......@@ -175,6 +175,8 @@ DEFINE_IMPLICATION(harmony, harmony_arrow_functions)
DEFINE_IMPLICATION(harmony, harmony_classes)
DEFINE_IMPLICATION(harmony, harmony_object_literals)
DEFINE_IMPLICATION(harmony_modules, harmony_scoping)
DEFINE_IMPLICATION(harmony_classes, harmony_scoping)
DEFINE_IMPLICATION(harmony_classes, harmony_object_literals)
DEFINE_IMPLICATION(harmony, es_staging)
......
......@@ -33,18 +33,22 @@ void BreakableStatementChecker::VisitVariableDeclaration(
VariableDeclaration* decl) {
}
void BreakableStatementChecker::VisitFunctionDeclaration(
FunctionDeclaration* decl) {
}
void BreakableStatementChecker::VisitModuleDeclaration(
ModuleDeclaration* decl) {
}
void BreakableStatementChecker::VisitImportDeclaration(
ImportDeclaration* decl) {
}
void BreakableStatementChecker::VisitExportDeclaration(
ExportDeclaration* decl) {
}
......@@ -178,6 +182,13 @@ void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) {
if (expr->extends() != NULL) {
Visit(expr->extends());
}
}
void BreakableStatementChecker::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
}
......@@ -1531,6 +1542,16 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void FullCodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
// TODO(arv): Implement
Comment cmnt(masm_, "[ ClassLiteral");
if (expr->extends() != NULL) {
VisitForEffect(expr->extends());
}
context()->Plug(isolate()->factory()->undefined_value());
}
void FullCodeGenerator::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
Comment cmnt(masm_, "[ NativeFunctionLiteral");
......
......@@ -5248,6 +5248,14 @@ void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void HOptimizedGraphBuilder::VisitClassLiteral(ClassLiteral* lit) {
DCHECK(!HasStackOverflow());
DCHECK(current_block() != NULL);
DCHECK(current_block()->HasPredecessor());
return Bailout(kClassLiteral);
}
void HOptimizedGraphBuilder::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
DCHECK(!HasStackOverflow());
......
......@@ -8,6 +8,7 @@ var kMessages = {
// Error
cyclic_proto: ["Cyclic __proto__ value"],
code_gen_from_strings: ["%0"],
constructor_special_method: ["Class constructor may not be an accessor"],
generator_running: ["Generator is already running"],
generator_finished: ["Generator has already finished"],
// TypeError
......@@ -139,6 +140,7 @@ var kMessages = {
array_indexof_not_defined: ["Array.getIndexOf: Argument undefined"],
object_not_extensible: ["Can't add property ", "%0", ", object is not extensible"],
illegal_access: ["Illegal access"],
static_prototype: ["Classes may not have static property named prototype"],
strict_mode_with: ["Strict mode code may not include a with statement"],
strict_eval_arguments: ["Unexpected eval or arguments in strict mode"],
too_many_arguments: ["Too many arguments in function call (only 65535 allowed)"],
......
......@@ -1016,6 +1016,7 @@ template <class C> inline bool Is(Object* obj);
"Call to a JavaScript runtime function") \
V(kCannotTranslatePositionInChangedArea, \
"Cannot translate position in changed area") \
V(kClassLiteral, "Class literal") \
V(kCodeGenerationFailed, "Code generation failed") \
V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \
V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \
......
......@@ -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);
......
......@@ -363,6 +363,7 @@ class ParserTraits {
typedef v8::internal::Expression* Expression;
typedef Yield* YieldExpression;
typedef v8::internal::FunctionLiteral* FunctionLiteral;
typedef v8::internal::ClassLiteral* ClassLiteral;
typedef v8::internal::Literal* Literal;
typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
......@@ -401,6 +402,10 @@ class ParserTraits {
static bool IsIdentifier(Expression* expression);
bool IsPrototype(const AstRawString* identifier) const;
bool IsConstructor(const AstRawString* identifier) const;
static const AstRawString* AsIdentifier(Expression* expression) {
DCHECK(IsIdentifier(expression));
return expression->AsVariableProxy()->raw_name();
......@@ -518,6 +523,8 @@ class ParserTraits {
return NULL;
}
static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
static ClassLiteral* EmptyClassLiteral() { return NULL; }
// Used in error return values.
static ZoneList<Expression*>* NullExpressionList() {
......@@ -705,6 +712,8 @@ class Parser : public ParserBase<ParserTraits> {
Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
bool* ok);
Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
bool* ok);
Statement* ParseNativeDeclaration(bool* ok);
Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
Block* ParseVariableStatement(VariableDeclarationContext var_context,
......
......@@ -78,6 +78,12 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
if (scanner->UnescapedLiteralMatches("arguments", 9)) {
return PreParserIdentifier::Arguments();
}
if (scanner->UnescapedLiteralMatches("prototype", 9)) {
return PreParserIdentifier::Prototype();
}
if (scanner->UnescapedLiteralMatches("constructor", 11)) {
return PreParserIdentifier::Constructor();
}
return PreParserIdentifier::Default();
}
......@@ -178,6 +184,8 @@ PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
switch (peek()) {
case Token::FUNCTION:
return ParseFunctionDeclaration(ok);
case Token::CLASS:
return ParseClassDeclaration(ok);
case Token::CONST:
return ParseVariableStatement(kSourceElement, ok);
case Token::LET:
......@@ -305,6 +313,9 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
}
}
case Token::CLASS:
return ParseClassDeclaration(CHECK_OK);
case Token::DEBUGGER:
return ParseDebuggerStatement(ok);
......@@ -345,6 +356,18 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
}
PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
Expect(Token::CLASS, CHECK_OK);
int pos = position();
bool is_strict_reserved = false;
Identifier name =
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
CHECK_OK);
return Statement::Default();
}
PreParser::Statement PreParser::ParseBlock(bool* ok) {
// Block ::
// '{' Statement* '}'
......
This diff is collapsed.
......@@ -289,6 +289,21 @@ void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
}
void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) {
Print("(class ");
PrintLiteral(node->name(), false);
if (node->extends()) {
Print(" extends ");
Visit(node->extends());
}
Print(" { ");
for (int i = 0; i < node->properties()->length(); i++) {
PrintObjectLiteralProperty(node->properties()->at(i));
}
Print(" })");
}
void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
Print("(");
PrintLiteral(node->name(), false);
......@@ -323,16 +338,22 @@ void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
Print("{ ");
for (int i = 0; i < node->properties()->length(); i++) {
if (i != 0) Print(",");
ObjectLiteral::Property* property = node->properties()->at(i);
Print(" ");
Visit(property->key());
Print(": ");
Visit(property->value());
PrintObjectLiteralProperty(node->properties()->at(i));
}
Print(" }");
}
void PrettyPrinter::PrintObjectLiteralProperty(
ObjectLiteralProperty* property) {
// TODO(arv): Better printing of methods etc.
Print(" ");
Visit(property->key());
Print(": ");
Visit(property->value());
}
void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
Print("[ ");
for (int i = 0; i < node->values()->length(); i++) {
......@@ -969,6 +990,12 @@ void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
}
void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
IndentedScope indent(this, "CLASS LITERAL");
PrintLiteralIndented("NAME", node->name(), false);
}
void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
IndentedScope indent(this, "NATIVE FUNC LITERAL");
PrintLiteralIndented("NAME", node->name(), false);
......
......@@ -52,6 +52,7 @@ class PrettyPrinter: public AstVisitor {
void PrintDeclarations(ZoneList<Declaration*>* declarations);
void PrintFunctionLiteral(FunctionLiteral* function);
void PrintCaseClause(CaseClause* clause);
void PrintObjectLiteralProperty(ObjectLiteralProperty* property);
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
};
......
This diff is collapsed.
......@@ -653,7 +653,7 @@ class Scanner {
bool harmony_modules_;
// Whether we scan 0o777 and 0b111 as numbers.
bool harmony_numeric_literals_;
// Whether we scan 'super' as keyword.
// Whether we scan 'class', 'extends', 'static' and 'super' as keywords.
bool harmony_classes_;
};
......
......@@ -148,10 +148,13 @@ namespace internal {
/* Future reserved words (ECMA-262, section 7.6.1.2). */ \
T(FUTURE_RESERVED_WORD, NULL, 0) \
T(FUTURE_STRICT_RESERVED_WORD, NULL, 0) \
K(CLASS, "class", 0) \
K(CONST, "const", 0) \
K(EXPORT, "export", 0) \
K(EXTENDS, "extends", 0) \
K(IMPORT, "import", 0) \
K(LET, "let", 0) \
K(STATIC, "static", 0) \
K(YIELD, "yield", 0) \
K(SUPER, "super", 0) \
\
......
......@@ -352,6 +352,9 @@ void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
void AstTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment