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}
This commit is contained in:
Andreas Rossberg 2014-11-20 11:51:49 +01:00
parent fbcfce69aa
commit 1808badc2d
9 changed files with 205 additions and 118 deletions

View File

@ -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<JSObject> 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++) {

View File

@ -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")

View File

@ -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"],
};

View File

@ -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<const AstRawString*>* 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<const AstRawString*>* 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.

View File

@ -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();
}

View File

@ -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<Traits>::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<Traits>::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<Traits>::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<Traits>::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);

View File

@ -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<i::String> FormatMessage(i::Vector<unsigned> data) {
enum ParserFlag {
kAllowLazy,
kAllowNativesSyntax,
kAllowNatives,
kAllowHarmonyScoping,
kAllowModules,
kAllowHarmonyModules,
kAllowHarmonyNumericLiterals,
kAllowArrowFunctions,
kAllowClasses,
kAllowHarmonyArrowFunctions,
kAllowHarmonyClasses,
kAllowHarmonyObjectLiterals,
kAllowHarmonyTemplates
kAllowHarmonyTemplates,
kAllowHarmonySloppy
};
@ -1360,16 +1361,18 @@ template <typename Traits>
void SetParserFlags(i::ParserBase<Traits>* parser,
i::EnumSet<ParserFlag> 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<i::String> 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<v8::Context> 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));
}

View File

@ -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; }");

View File

@ -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 {}