[modules] Treat top-level functions as lexical
[15.2.1.11 Static Semantics: LexicallyDeclaredNames](https://tc39.github.io/ecma262/#sec-module-semantics-static-semantics-lexicallydeclarednames) (in contrast with its definition for StatementListItem) makes no explicit provision for HoistableDeclarations. This means that function declarations are treated as lexically scoped in module code, as described in section 15.2.1.11's informative note: > At the top level of a function, or script, function declarations are > treated like var declarations rather than like lexical declarations. BUG=v8:4884 LOG=N R=adamk@chromium.org Review URL: https://codereview.chromium.org/1851673007 Cr-Commit-Position: refs/heads/master@{#35633}
This commit is contained in:
parent
59546149c6
commit
43fa3e65c9
@ -2085,7 +2085,9 @@ Statement* Parser::ParseFunctionDeclaration(
|
||||
// initial value upon entering the corresponding scope.
|
||||
// In ES6, a function behaves as a lexical binding, except in
|
||||
// a script scope, or the initial scope of eval or another function.
|
||||
VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR;
|
||||
VariableMode mode =
|
||||
(!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET
|
||||
: VAR;
|
||||
VariableProxy* proxy = NewUnresolved(name, mode);
|
||||
Declaration* declaration =
|
||||
factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
|
||||
|
@ -5628,6 +5628,43 @@ TEST(ImportExportParsingErrors) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ModuleTopLevelFunctionDecl) {
|
||||
// clang-format off
|
||||
const char* kErrorSources[] = {
|
||||
"function f() {} function f() {}",
|
||||
"var f; function f() {}",
|
||||
"function f() {} var f;",
|
||||
"function* f() {} function* f() {}",
|
||||
"var f; function* f() {}",
|
||||
"function* f() {} var f;",
|
||||
"function f() {} function* f() {}",
|
||||
"function* f() {} function f() {}",
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
|
||||
v8::HandleScope handles(CcTest::isolate());
|
||||
v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
|
||||
for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
|
||||
i::Handle<i::String> source =
|
||||
factory->NewStringFromAsciiChecked(kErrorSources[i]);
|
||||
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::Zone zone(CcTest::i_isolate()->allocator());
|
||||
i::ParseInfo info(&zone, script);
|
||||
i::Parser parser(&info);
|
||||
info.set_module();
|
||||
CHECK(!parser.Parse(&info));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(ModuleParsingInternals) {
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
|
Loading…
Reference in New Issue
Block a user