njs: block scoped function definitions support.
overview function definitions are block scoped:
root@node:~# cat test.mjs
function test() {
console.log('top');
}
{
setImmediate(test);
function test() {
console.log('block1');
}
}
{
function test() {
console.log('block2');
}
setImmediate(test);
{
function test() {
console.log('block3');
}
setImmediate(test);
}
}
test();
root@node:~# node --experimental-modules test.mjs
(node:4894) ExperimentalWarning: The ESM module loader is experimental.
top
block1
block2
block3
only top or block level definitions are allowed:
root@node:~# cat test1.mjs
if (true) function test() {}
root@node:~# node --experimental-modules test1.mjs
(node:4976) ExperimentalWarning: The ESM module loader is experimental.
file:///root/test1.mjs:1
if (true) function test() {}
^^^^^^^^
SyntaxError: In strict mode code, functions can only be declared at top level or inside a block.
at translators.set (internal/modules/esm/translators.js:51:18)
and some weird resolution rules:
root@node:~# cat test2.mjs
// At the top level of a function, or script,
// function declarations are treated like var declarations
// rather than like lexical declarations.
function fblock() {
var test;
function test() {
}
}
// But not at the top level of a module!
function test() {}
var test;
root@node:~# node --experimental-modules test2.mjs
(node:5018) ExperimentalWarning: The ESM module loader is experimental.
file:///root/test2.mjs:12
var test;
^
SyntaxError: Identifier 'test' has already been declared
at translators.set (internal/modules/esm/translators.js:51:18)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 34 (34 by maintainers)
Commits related to this issue
- Added block scoped function definitions support. This closes #134 issue on Github. — committed to nginx/njs by hongzhidao 5 years ago
@drsm @xeioex
Updated. https://gist.github.com/hongzhidao/4f4e902bfec4a44834f93aa77dbfb19d
@hongzhidao
you need
--summaryoption.@xeioex
I thought about it. Essentially we need two different things to store the added variable information:
scope->declared_varsandscope->variables.scope-> declared_varsis required in each scope and will be used to check duplicated declarations as needed,scope->variablesis kept the current way. Now we combine them together.BTW, how do you get the result like below? the percentage of pass, for example
25.2%.I updated it again, spliting it into separate patches 😃 https://gist.github.com/hongzhidao/4f4e902bfec4a44834f93aa77dbfb19d
;{ function f() {} { var f }}
Is it a problem? Get it, yes.
--command='<full path to njs cli binary> -q'to disable filenames in output of exceptions (randoms filenames are used by tests)diff -u test262_njs_orig.log test262_njs_after.logThere are four cases:
Cases 1. and 3. are identical. I use block in tests because node’s REPL doesn’t support evaluation as a module.
let f)The cases 2. and 4. are identical.
vardeclared variable.vardeclared stuff.We have to change our module wrapper from
to
to support the feature.
@drsm
My understand.
if (1) x, there is no scope inside if.Right?