From 1808badc2d83432af0e9fd1ba5bf49e40f279b39 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 20 Nov 2014 11:51:49 +0100 Subject: [PATCH] Disable classes in sloppy mode unless --harmony-sloppy is set Also clean up flag names a little. Baseline: https://codereview.chromium.org/713413003/ R=arv@chromium.org, dslomov@chromium.org BUG= Review URL: https://codereview.chromium.org/722203006 Cr-Commit-Position: refs/heads/master@{#25435} --- src/bootstrapper.cc | 3 + src/flag-definitions.h | 3 +- src/messages.js | 2 +- src/parser.cc | 37 ++-- src/preparser.cc | 12 +- src/preparser.h | 49 +++-- test/cctest/test-parsing.cc | 205 +++++++++++------- .../harmony/block-non-strict-errors.js | 10 +- test/mjsunit/harmony/classes.js | 2 +- 9 files changed, 205 insertions(+), 118 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 505b7845ec..02af9d2fbc 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1598,6 +1598,7 @@ EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrow_functions) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_numeric_literals) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_tostring) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_templates) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sloppy) void Genesis::InstallNativeFunctions_harmony_proxies() { @@ -1625,6 +1626,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_numeric_literals) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tostring) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_templates) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy) void Genesis::InitializeGlobal_harmony_regexps() { Handle builtins(native_context()->builtins()); @@ -2180,6 +2182,7 @@ bool Genesis::InstallExperimentalNatives() { NULL}; static const char* harmony_templates_natives[] = { "native harmony-templates.js", NULL}; + static const char* harmony_sloppy_natives[] = {NULL}; for (int i = ExperimentalNatives::GetDebuggerCount(); i < ExperimentalNatives::GetBuiltinsCount(); i++) { diff --git a/src/flag-definitions.h b/src/flag-definitions.h index c6c56f2c41..535dcd2d7b 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -173,7 +173,8 @@ DEFINE_IMPLICATION(harmony, es_staging) V(harmony_arrow_functions, "harmony arrow functions") \ V(harmony_tostring, "harmony toString") \ V(harmony_proxies, "harmony proxies") \ - V(harmony_templates, "harmony template literals") + V(harmony_templates, "harmony template literals") \ + V(harmony_sloppy, "harmony features in sloppy mode") // Features that are complete (but still behind --harmony/es-staging flag). #define HARMONY_STAGED(V) V(harmony_strings, "harmony string methods") diff --git a/src/messages.js b/src/messages.js index bd6fbfd3ed..142e47bcc0 100644 --- a/src/messages.js +++ b/src/messages.js @@ -181,7 +181,7 @@ var kMessages = { extends_value_not_a_function: ["Class extends value ", "%0", " is not a function or null"], prototype_parent_not_an_object: ["Class extends value does not have valid prototype property ", "%0"], duplicate_constructor: ["A class may only have one constructor"], - lexical_strict_mode: ["Lexical declarations are currently only allowed in strict mode"], + sloppy_lexical: ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"], }; diff --git a/src/parser.cc b/src/parser.cc index 5e7530496b..f716c41418 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -795,15 +795,16 @@ Parser::Parser(CompilationInfo* info, ParseInfo* parse_info) total_preparse_skipped_(0), pre_parse_timer_(NULL) { DCHECK(!script().is_null() || info->source_stream() != NULL); - set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); - set_allow_modules(!info->is_native() && FLAG_harmony_modules); - set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); set_allow_lazy(false); // Must be explicitly enabled. - set_allow_arrow_functions(FLAG_harmony_arrow_functions); + set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); + set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); + set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); + set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); - set_allow_classes(FLAG_harmony_classes); + set_allow_harmony_classes(FLAG_harmony_classes); set_allow_harmony_object_literals(FLAG_harmony_object_literals); set_allow_harmony_templates(FLAG_harmony_templates); + set_allow_harmony_sloppy(FLAG_harmony_sloppy); for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; ++feature) { use_counts_[feature] = 0; @@ -916,7 +917,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, // Compute the parsing mode. Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; - if (allow_natives_syntax() || extension_ != NULL || + if (allow_natives() || extension_ != NULL || (*scope)->is_eval_scope()) { mode = PARSE_EAGERLY; } @@ -1992,6 +1993,12 @@ Statement* Parser::ParseClassDeclaration(ZoneList* names, // so rewrite it as such. Expect(Token::CLASS, CHECK_OK); + if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { + ReportMessage("sloppy_lexical"); + *ok = false; + return NULL; + } + int pos = position(); bool is_strict_reserved = false; const AstRawString* name = @@ -2489,7 +2496,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement( if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && expr->AsVariableProxy()->raw_name() == ast_value_factory()->let_string()) { - ReportMessage("lexical_strict_mode", NULL); + ReportMessage("sloppy_lexical", NULL); *ok = false; return NULL; } @@ -3373,7 +3380,7 @@ Statement* Parser::ParseForStatement(ZoneList* labels, // Detect attempts at 'let' declarations in sloppy mode. if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && is_let_identifier_expression) { - ReportMessage("lexical_strict_mode", NULL); + ReportMessage("sloppy_lexical", NULL); *ok = false; return NULL; } @@ -3964,17 +3971,19 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( if (reusable_preparser_ == NULL) { reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); - reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); - reusable_preparser_->set_allow_modules(allow_modules()); - reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); reusable_preparser_->set_allow_lazy(true); - reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); + reusable_preparser_->set_allow_natives(allow_natives()); + reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); + reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); + reusable_preparser_->set_allow_harmony_arrow_functions( + allow_harmony_arrow_functions()); reusable_preparser_->set_allow_harmony_numeric_literals( allow_harmony_numeric_literals()); - reusable_preparser_->set_allow_classes(allow_classes()); + reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); reusable_preparser_->set_allow_harmony_object_literals( allow_harmony_object_literals()); reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates()); + reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); } PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(strict_mode(), @@ -5109,7 +5118,7 @@ bool Parser::Parse() { DCHECK(info()->function() == NULL); FunctionLiteral* result = NULL; pre_parse_timer_ = isolate()->counters()->pre_parse(); - if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) { + if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { // If intrinsics are allowed, the Parser cannot operate independent of the // V8 heap because of Runtime. Tell the string table to internalize strings // and values right after they're created. diff --git a/src/preparser.cc b/src/preparser.cc index 6b0d7d9d6d..1bd33409f0 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -350,6 +350,12 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { Expect(Token::CLASS, CHECK_OK); + if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { + ReportMessage("sloppy_lexical"); + *ok = false; + return Statement::Default(); + } + int pos = position(); bool is_strict_reserved = false; Identifier name = @@ -512,7 +518,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { // Detect attempts at 'let' declarations in sloppy mode. if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { - ReportMessage("lexical_strict_mode", NULL); + ReportMessage("sloppy_lexical", NULL); *ok = false; return Statement::Default(); } @@ -733,7 +739,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { // Detect attempts at 'let' declarations in sloppy mode. if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && is_let_identifier_expression) { - ReportMessage("lexical_strict_mode", NULL); + ReportMessage("sloppy_lexical", NULL); *ok = false; return Statement::Default(); } @@ -998,7 +1004,7 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { // CallRuntime :: // '%' Identifier Arguments Expect(Token::MOD, CHECK_OK); - if (!allow_natives_syntax()) { + if (!allow_natives()) { *ok = false; return Expression::Default(); } diff --git a/src/preparser.h b/src/preparser.h index a9db265951..bdab177585 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -83,46 +83,59 @@ class ParserBase : public Traits { scanner_(scanner), stack_overflow_(false), allow_lazy_(false), - allow_natives_syntax_(false), - allow_arrow_functions_(false), + allow_natives_(false), + allow_harmony_arrow_functions_(false), allow_harmony_object_literals_(false), + allow_harmony_sloppy_(false), zone_(zone) {} // Getters that indicate whether certain syntactical constructs are // allowed to be parsed by this instance of the parser. bool allow_lazy() const { return allow_lazy_; } - bool allow_natives_syntax() const { return allow_natives_syntax_; } - bool allow_arrow_functions() const { return allow_arrow_functions_; } - bool allow_modules() const { return scanner()->HarmonyModules(); } + bool allow_natives() const { return allow_natives_; } + bool allow_harmony_arrow_functions() const { + return allow_harmony_arrow_functions_; + } + bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } bool allow_harmony_numeric_literals() const { return scanner()->HarmonyNumericLiterals(); } - bool allow_classes() const { return scanner()->HarmonyClasses(); } + bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } bool allow_harmony_object_literals() const { return allow_harmony_object_literals_; } bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } + bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } // Setters that determine whether certain syntactical constructs are // allowed to be parsed by this instance of the parser. void set_allow_lazy(bool allow) { allow_lazy_ = allow; } - void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } - void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } - void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } + void set_allow_natives(bool allow) { allow_natives_ = allow; } + void set_allow_harmony_arrow_functions(bool allow) { + allow_harmony_arrow_functions_ = allow; + } + void set_allow_harmony_modules(bool allow) { + scanner()->SetHarmonyModules(allow); + } void set_allow_harmony_scoping(bool allow) { scanner()->SetHarmonyScoping(allow); } void set_allow_harmony_numeric_literals(bool allow) { scanner()->SetHarmonyNumericLiterals(allow); } - void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); } + void set_allow_harmony_classes(bool allow) { + scanner()->SetHarmonyClasses(allow); + } void set_allow_harmony_object_literals(bool allow) { allow_harmony_object_literals_ = allow; } void set_allow_harmony_templates(bool allow) { scanner()->SetHarmonyTemplates(allow); } + void set_allow_harmony_sloppy(bool allow) { + allow_harmony_sloppy_ = allow; + } protected: enum AllowEvalOrArgumentsAsIdentifier { @@ -577,9 +590,10 @@ class ParserBase : public Traits { bool stack_overflow_; bool allow_lazy_; - bool allow_natives_syntax_; - bool allow_arrow_functions_; + bool allow_natives_; + bool allow_harmony_arrow_functions_; bool allow_harmony_object_literals_; + bool allow_harmony_sloppy_; typename Traits::Type::Zone* zone_; // Only used by Parser. }; @@ -1823,7 +1837,7 @@ ParserBase::ParsePrimaryExpression(bool* ok) { case Token::LPAREN: Consume(Token::LPAREN); - if (allow_arrow_functions() && peek() == Token::RPAREN) { + if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { // Arrow functions are the only expression type constructions // for which an empty parameter list "()" is valid input. Consume(Token::RPAREN); @@ -1841,6 +1855,11 @@ ParserBase::ParsePrimaryExpression(bool* ok) { case Token::CLASS: { Consume(Token::CLASS); + if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { + ReportMessage("sloppy_lexical", NULL); + *ok = false; + break; + } int class_token_position = position(); IdentifierT name = this->EmptyIdentifier(); bool is_strict_reserved_name = false; @@ -1863,7 +1882,7 @@ ParserBase::ParsePrimaryExpression(bool* ok) { break; case Token::MOD: - if (allow_natives_syntax() || extension_ != NULL) { + if (allow_natives() || extension_ != NULL) { result = this->ParseV8Intrinsic(CHECK_OK); break; } @@ -2191,7 +2210,7 @@ ParserBase::ParseAssignmentExpression(bool accept_IN, bool* ok) { ExpressionT expression = this->ParseConditionalExpression(accept_IN, CHECK_OK); - if (allow_arrow_functions() && peek() == Token::ARROW) { + if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { checkpoint.Restore(); expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression, CHECK_OK); diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index b6294ea1d9..99965d2aeb 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -319,8 +319,8 @@ TEST(StandAlonePreParser) { i::PreParser preparser(&scanner, &log, stack_limit); preparser.set_allow_lazy(true); - preparser.set_allow_natives_syntax(true); - preparser.set_allow_arrow_functions(true); + preparser.set_allow_natives(true); + preparser.set_allow_harmony_arrow_functions(true); i::PreParser::PreParseResult result = preparser.PreParseProgram(); CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK(!log.HasError()); @@ -499,7 +499,7 @@ TEST(PreParseOverflow) { i::PreParser preparser(&scanner, &log, stack_limit); preparser.set_allow_lazy(true); - preparser.set_allow_arrow_functions(true); + preparser.set_allow_harmony_arrow_functions(true); i::PreParser::PreParseResult result = preparser.PreParseProgram(); CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); } @@ -1017,8 +1017,8 @@ TEST(ScopeUsesArgumentsSuperThis) { isolate->heap()->HashSeed(), isolate->unicode_cache()}; i::Parser parser(&info, &parse_info); - parser.set_allow_arrow_functions(true); - parser.set_allow_classes(true); + parser.set_allow_harmony_arrow_functions(true); + parser.set_allow_harmony_classes(true); parser.set_allow_harmony_scoping(true); info.MarkAsGlobal(); parser.Parse(); @@ -1265,7 +1265,7 @@ TEST(ScopePositions) { i::Parser parser(&info, &parse_info); parser.set_allow_lazy(true); parser.set_allow_harmony_scoping(true); - parser.set_allow_arrow_functions(true); + parser.set_allow_harmony_arrow_functions(true); info.MarkAsGlobal(); info.SetStrictMode(source_data[i].strict_mode); parser.Parse(); @@ -1339,14 +1339,15 @@ i::Handle FormatMessage(i::Vector data) { enum ParserFlag { kAllowLazy, - kAllowNativesSyntax, + kAllowNatives, kAllowHarmonyScoping, - kAllowModules, + kAllowHarmonyModules, kAllowHarmonyNumericLiterals, - kAllowArrowFunctions, - kAllowClasses, + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, kAllowHarmonyObjectLiterals, - kAllowHarmonyTemplates + kAllowHarmonyTemplates, + kAllowHarmonySloppy }; @@ -1360,16 +1361,18 @@ template void SetParserFlags(i::ParserBase* parser, i::EnumSet flags) { parser->set_allow_lazy(flags.Contains(kAllowLazy)); - parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); + parser->set_allow_natives(flags.Contains(kAllowNatives)); parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); - parser->set_allow_modules(flags.Contains(kAllowModules)); + parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules)); parser->set_allow_harmony_numeric_literals( flags.Contains(kAllowHarmonyNumericLiterals)); parser->set_allow_harmony_object_literals( flags.Contains(kAllowHarmonyObjectLiterals)); - parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions)); - parser->set_allow_classes(flags.Contains(kAllowClasses)); + parser->set_allow_harmony_arrow_functions( + flags.Contains(kAllowHarmonyArrowFunctions)); + parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses)); parser->set_allow_harmony_templates(flags.Contains(kAllowHarmonyTemplates)); + parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy)); } @@ -1482,7 +1485,9 @@ void TestParserSync(const char* source, size_t varying_flags_length, ParserSyncTestResult result = kSuccessOrError, const ParserFlag* always_true_flags = NULL, - size_t always_true_flags_length = 0) { + size_t always_true_flags_length = 0, + const ParserFlag* always_false_flags = NULL, + size_t always_false_flags_length = 0) { i::Handle str = CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); for (int bits = 0; bits < (1 << varying_flags_length); bits++) { @@ -1495,6 +1500,10 @@ void TestParserSync(const char* source, ++flag_index) { flags.Add(always_true_flags[flag_index]); } + for (size_t flag_index = 0; flag_index < always_false_flags_length; + ++flag_index) { + flags.Remove(always_false_flags[flag_index]); + } TestParserSyncWithFlags(str, flags, result); } } @@ -1578,13 +1587,14 @@ TEST(ParserSync) { i::GetCurrentStackPosition() - 128 * 1024); static const ParserFlag flags1[] = { - kAllowArrowFunctions, - kAllowClasses, + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, kAllowHarmonyNumericLiterals, kAllowHarmonyObjectLiterals, kAllowHarmonyScoping, + kAllowHarmonyModules, + kAllowHarmonySloppy, kAllowLazy, - kAllowModules, }; for (int i = 0; context_data[i][0] != NULL; ++i) { @@ -1618,7 +1628,7 @@ TEST(ParserSync) { TestParserSync("0o1234", flags2, arraysize(flags2)); TestParserSync("0b1011", flags2, arraysize(flags2)); - static const ParserFlag flags3[] = { kAllowNativesSyntax }; + static const ParserFlag flags3[] = { kAllowNatives }; TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3)); } @@ -1652,7 +1662,9 @@ void RunParserSyncTest(const char* context_data[][2], const ParserFlag* flags = NULL, int flags_len = 0, const ParserFlag* always_true_flags = NULL, - int always_true_flags_len = 0) { + int always_true_len = 0, + const ParserFlag* always_false_flags = NULL, + int always_false_len = 0) { v8::HandleScope handles(CcTest::isolate()); v8::Handle context = v8::Context::New(CcTest::isolate()); v8::Context::Scope context_scope(context); @@ -1661,36 +1673,41 @@ void RunParserSyncTest(const char* context_data[][2], i::GetCurrentStackPosition() - 128 * 1024); static const ParserFlag default_flags[] = { - kAllowArrowFunctions, - kAllowClasses, + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, kAllowHarmonyNumericLiterals, kAllowHarmonyObjectLiterals, kAllowHarmonyScoping, + kAllowHarmonyModules, + kAllowHarmonyTemplates, + kAllowHarmonySloppy, kAllowLazy, - kAllowModules, - kAllowNativesSyntax, - kAllowHarmonyTemplates + kAllowNatives, }; ParserFlag* generated_flags = NULL; if (flags == NULL) { flags = default_flags; flags_len = arraysize(default_flags); - if (always_true_flags != NULL) { - // Remove always_true_flags from default_flags. - CHECK(always_true_flags_len < flags_len); - generated_flags = new ParserFlag[flags_len - always_true_flags_len]; + if (always_true_flags != NULL || always_false_flags != NULL) { + // Remove always_true/false_flags from default_flags. + CHECK((always_true_flags != NULL) == (always_true_len > 0)); + CHECK((always_false_flags != NULL) == (always_false_len > 0)); + CHECK(always_true_flags == NULL || always_true_len < flags_len); + CHECK(always_false_flags == NULL || always_false_len < flags_len); + generated_flags = + new ParserFlag[flags_len - always_true_len - always_false_len]; int flag_index = 0; for (int i = 0; i < flags_len; ++i) { bool use_flag = true; - for (int j = 0; j < always_true_flags_len; ++j) { - if (flags[i] == always_true_flags[j]) { - use_flag = false; - break; - } + for (int j = 0; use_flag && j < always_true_len; ++j) { + if (flags[i] == always_true_flags[j]) use_flag = false; + } + for (int j = 0; use_flag && j < always_false_len; ++j) { + if (flags[i] == always_false_flags[j]) use_flag = false; } if (use_flag) generated_flags[flag_index++] = flags[i]; } - CHECK(flag_index == flags_len - always_true_flags_len); + CHECK(flag_index == flags_len - always_true_len - always_false_len); flags_len = flag_index; flags = generated_flags; } @@ -1715,7 +1732,9 @@ void RunParserSyncTest(const char* context_data[][2], flags_len, result, always_true_flags, - always_true_flags_len); + always_true_len, + always_false_flags, + always_false_len); } } delete[] generated_flags; @@ -1822,7 +1841,7 @@ TEST(NoErrorsEvalAndArgumentsStrict) { NULL }; - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -1878,12 +1897,12 @@ TEST(ErrorsFutureStrictReservedWords) { NULL }; - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, arraysize(always_flags)); static const ParserFlag classes_flags[] = { - kAllowArrowFunctions, kAllowClasses, kAllowHarmonyScoping}; + kAllowHarmonyArrowFunctions, kAllowHarmonyClasses, kAllowHarmonyScoping}; RunParserSyncTest(context_data, statement_data, kError, NULL, 0, classes_flags, arraysize(classes_flags)); } @@ -1905,12 +1924,12 @@ TEST(NoErrorsFutureStrictReservedWords) { NULL }; - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); static const ParserFlag classes_flags[] = { - kAllowArrowFunctions, kAllowClasses, kAllowHarmonyScoping}; + kAllowHarmonyArrowFunctions, kAllowHarmonyClasses, kAllowHarmonyScoping}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, classes_flags, arraysize(classes_flags)); } @@ -2323,7 +2342,7 @@ TEST(NoErrorsIllegalWordsAsLabels) { NULL }; - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -2344,7 +2363,7 @@ TEST(NoErrorsFutureStrictReservedAsLabelsSloppy) { }; #undef LABELLED_WHILE - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -2596,9 +2615,9 @@ TEST(Intrinsics) { NULL }; - // This test requires kAllowNativesSyntax to succeed. + // This test requires kAllowNatives to succeed. static const ParserFlag always_true_flags[] = { - kAllowNativesSyntax + kAllowNatives }; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, @@ -3483,7 +3502,7 @@ TEST(ErrorsArrowFunctions) { // The test is quite slow, so run it with a reduced set of flags. static const ParserFlag flags[] = {kAllowLazy, kAllowHarmonyScoping}; - static const ParserFlag always_flags[] = { kAllowArrowFunctions }; + static const ParserFlag always_flags[] = { kAllowHarmonyArrowFunctions }; RunParserSyncTest(context_data, statement_data, kError, flags, arraysize(flags), always_flags, arraysize(always_flags)); } @@ -3537,7 +3556,7 @@ TEST(NoErrorsArrowFunctions) { NULL }; - static const ParserFlag always_flags[] = {kAllowArrowFunctions}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -3562,7 +3581,7 @@ TEST(NoErrorsSuper) { "z.super", // Ok, property lookup. NULL}; - static const ParserFlag always_flags[] = {kAllowClasses}; + static const ParserFlag always_flags[] = {kAllowHarmonyClasses}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -3581,7 +3600,7 @@ TEST(ErrorsSuper) { "f(super)", NULL}; - static const ParserFlag always_flags[] = {kAllowClasses}; + static const ParserFlag always_flags[] = {kAllowHarmonyClasses}; RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, arraysize(always_flags)); } @@ -3764,7 +3783,8 @@ TEST(ClassExpressionNoErrors) { "class name extends class base {} {}", NULL}; - static const ParserFlag always_flags[] = {kAllowClasses}; + static const ParserFlag always_flags[] = { + kAllowHarmonyClasses, kAllowHarmonySloppy}; RunParserSyncTest(context_data, class_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -3783,7 +3803,8 @@ TEST(ClassDeclarationNoErrors) { "class name extends class base {} {}", NULL}; - static const ParserFlag always_flags[] = {kAllowClasses}; + static const ParserFlag always_flags[] = { + kAllowHarmonyClasses, kAllowHarmonySloppy}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } @@ -3827,8 +3848,9 @@ TEST(ClassBodyNoErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -3885,8 +3907,9 @@ TEST(ClassPropertyNameNoErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -3916,8 +3939,9 @@ TEST(ClassExpressionErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -3953,8 +3977,9 @@ TEST(ClassDeclarationErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyNumericLiterals + kAllowHarmonyClasses, + kAllowHarmonyNumericLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -3983,8 +4008,9 @@ TEST(ClassNameErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_name, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4016,8 +4042,9 @@ TEST(ClassGetterParamNameErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_name, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4044,8 +4071,9 @@ TEST(ClassStaticPrototypeErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4071,8 +4099,9 @@ TEST(ClassSpecialConstructorErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4093,8 +4122,9 @@ TEST(ClassConstructorNoErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -4111,8 +4141,9 @@ TEST(ClassMultipleConstructorErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4133,8 +4164,9 @@ TEST(ClassMultiplePropertyNamesNoErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -4153,8 +4185,9 @@ TEST(ClassesAreStrictErrors) { NULL}; static const ParserFlag always_flags[] = { - kAllowClasses, - kAllowHarmonyObjectLiterals + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy }; RunParserSyncTest(context_data, class_body_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -4454,15 +4487,25 @@ TEST(LexicalScopingSloppyMode) { "for(let x = 1;;){}", "for(let x of []){}", "for(let x in []){}", + "class C {}", + "class C extends D {}", + "(class {})", + "(class extends D {})", + "(class C {})", + "(class C extends D {})", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyScoping}; - RunParserSyncTest(context_data, bad_data, kError, NULL, 0, always_flags, - arraysize(always_flags)); + static const ParserFlag always_true_flags[] = { + kAllowHarmonyScoping, kAllowHarmonyClasses}; + static const ParserFlag always_false_flags[] = {kAllowHarmonySloppy}; + RunParserSyncTest(context_data, bad_data, kError, NULL, 0, + always_true_flags, arraysize(always_true_flags), + always_false_flags, arraysize(always_false_flags)); const char* good_data[] = { "let = 1;", "for(let = 1;;){}", NULL}; - RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, + always_true_flags, arraysize(always_true_flags), + always_false_flags, arraysize(always_false_flags)); } diff --git a/test/mjsunit/harmony/block-non-strict-errors.js b/test/mjsunit/harmony/block-non-strict-errors.js index de27cd269f..11fa5c6a52 100644 --- a/test/mjsunit/harmony/block-non-strict-errors.js +++ b/test/mjsunit/harmony/block-non-strict-errors.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-scoping +// Flags: --harmony-scoping --harmony-classes function CheckError(source) { var exception = null; @@ -13,7 +13,7 @@ function CheckError(source) { } assertNotNull(exception); assertEquals( - "Lexical declarations are currently only allowed in strict mode", + "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode", exception.message); } @@ -28,6 +28,12 @@ CheckError("function f() { let x = 1; }"); CheckError("for (let x = 1; x < 1; x++) {}"); CheckError("for (let x of []) {}"); CheckError("for (let x in []) {}"); +CheckError("class C {}"); +CheckError("class C extends Array {}"); +CheckError("(class {});"); +CheckError("(class extends Array {});"); +CheckError("(class C {});"); +CheckError("(class C exends Array {});"); CheckOk("let = 1;"); CheckOk("{ let = 1; }"); diff --git a/test/mjsunit/harmony/classes.js b/test/mjsunit/harmony/classes.js index c8c25ff63b..416c9114b5 100644 --- a/test/mjsunit/harmony/classes.js +++ b/test/mjsunit/harmony/classes.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-classes +// Flags: --harmony-classes --harmony-sloppy (function TestBasics() { var C = class C {}