| Index: test/mjsunit/es6/block-sloppy-function.js
|
| diff --git a/test/mjsunit/es6/block-sloppy-function.js b/test/mjsunit/es6/block-sloppy-function.js
|
| index 41063b4618af509b1d15d3922df0c0a7dc5af126..e5f244774f673942a382c66703865ee33dfe758d 100644
|
| --- a/test/mjsunit/es6/block-sloppy-function.js
|
| +++ b/test/mjsunit/es6/block-sloppy-function.js
|
| @@ -109,6 +109,31 @@
|
| assertEquals('function', typeof f);
|
| })();
|
|
|
| +(function complexParams(a = 0) {
|
| + {
|
| + let y = 3;
|
| + function f(b = 0) {
|
| + y = 2;
|
| + }
|
| + f();
|
| + assertEquals(2, y);
|
| + }
|
| + assertEquals('function', typeof f);
|
| +})();
|
| +
|
| +(function complexVarParams(a = 0) {
|
| + var f;
|
| + {
|
| + let y = 3;
|
| + function f(b = 0) {
|
| + y = 2;
|
| + }
|
| + f();
|
| + assertEquals(2, y);
|
| + }
|
| + assertEquals('function', typeof f);
|
| +})();
|
| +
|
| (function conditional() {
|
| if (true) {
|
| function f() { return 1; }
|
| @@ -142,6 +167,46 @@
|
| assertEquals(2, f());
|
| })();
|
|
|
| +(function executionOrder() {
|
| + function getOuter() {
|
| + return f;
|
| + }
|
| + assertEquals('undefined', typeof getOuter());
|
| +
|
| + {
|
| + assertEquals('function', typeof f);
|
| + assertEquals('undefined', typeof getOuter());
|
| + function f () {}
|
| + assertEquals('function', typeof f);
|
| + assertEquals('function', typeof getOuter());
|
| + }
|
| +
|
| + assertEquals('function', typeof getOuter());
|
| +})();
|
| +
|
| +(function reassignBindings() {
|
| + function getOuter() {
|
| + return f;
|
| + }
|
| + assertEquals('undefined', typeof getOuter());
|
| +
|
| + {
|
| + assertEquals('function', typeof f);
|
| + assertEquals('undefined', typeof getOuter());
|
| + f = 1;
|
| + assertEquals('number', typeof f);
|
| + assertEquals('undefined', typeof getOuter());
|
| + function f () {}
|
| + assertEquals('number', typeof f);
|
| + assertEquals('number', typeof getOuter());
|
| + f = '';
|
| + assertEquals('string', typeof f);
|
| + assertEquals('number', typeof getOuter());
|
| + }
|
| +
|
| + assertEquals('number', typeof getOuter());
|
| +})();
|
| +
|
| // Test that shadowing arguments is fine
|
| (function shadowArguments(x) {
|
| assertArrayEquals([1], arguments);
|
| @@ -153,43 +218,242 @@
|
| assertEquals('function', typeof arguments);
|
| })(1);
|
|
|
| -// Shadow function parameter
|
| -(function shadowParameter(x) {
|
| +
|
| +// Don't shadow simple parameter
|
| +(function shadowingParameterDoesntBind(x) {
|
| assertEquals(1, x);
|
| {
|
| function x() {}
|
| }
|
| - assertEquals('function', typeof x);
|
| + assertEquals(1, x);
|
| })(1);
|
|
|
| -// Shadow function parameter
|
| -(function shadowDefaultParameter(x = 0) {
|
| +// Don't shadow complex parameter
|
| +(function shadowingDefaultParameterDoesntBind(x = 0) {
|
| + assertEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals(1, x);
|
| +})(1);
|
| +
|
| +// Don't shadow nested complex parameter
|
| +(function shadowingNestedParameterDoesntBind([[x]]) {
|
| + assertEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| assertEquals(1, x);
|
| +})([[1]]);
|
| +
|
| +// Don't shadow rest parameter
|
| +(function shadowingRestParameterDoesntBind(...x) {
|
| + assertArrayEquals([1], x);
|
| {
|
| function x() {}
|
| }
|
| - // TODO(littledan): Once destructured parameters are no longer
|
| - // let-bound, enable this assertion. This is the core of the test.
|
| - // assertEquals('function', typeof x);
|
| + assertArrayEquals([1], x);
|
| })(1);
|
|
|
| -(function shadowRestParameter(...x) {
|
| +// Don't shadow complex rest parameter
|
| +(function shadowingComplexRestParameterDoesntBind(...[x]) {
|
| + assertArrayEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertArrayEquals(1, x);
|
| +})(1);
|
| +
|
| +// Previous tests with a var declaration thrown in.
|
| +// Don't shadow simple parameter
|
| +(function shadowingVarParameterDoesntBind(x) {
|
| + var x;
|
| + assertEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals(1, x);
|
| +})(1);
|
| +
|
| +// Don't shadow complex parameter
|
| +(function shadowingVarDefaultParameterDoesntBind(x = 0) {
|
| + var x;
|
| + assertEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals(1, x);
|
| +})(1);
|
| +
|
| +// Don't shadow nested complex parameter
|
| +(function shadowingVarNestedParameterDoesntBind([[x]]) {
|
| + var x;
|
| + assertEquals(1, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals(1, x);
|
| +})([[1]]);
|
| +
|
| +// Don't shadow rest parameter
|
| +(function shadowingVarRestParameterDoesntBind(...x) {
|
| + var x;
|
| + assertArrayEquals([1], x);
|
| + {
|
| + function x() {}
|
| + }
|
| assertArrayEquals([1], x);
|
| +})(1);
|
| +
|
| +// Don't shadow complex rest parameter
|
| +(function shadowingVarComplexRestParameterDoesntBind(...[x]) {
|
| + var x;
|
| + assertArrayEquals(1, x);
|
| {
|
| function x() {}
|
| }
|
| - // TODO(littledan): Once destructured parameters are no longer
|
| - // let-bound, enable this assertion. This is the core of the test.
|
| - // assertEquals('function', typeof x);
|
| + assertArrayEquals(1, x);
|
| +})(1);
|
| +
|
| +
|
| +// Hoisting is not affected by other simple parameters
|
| +(function irrelevantParameterBinds(y, z) {
|
| + assertEquals(undefined, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals('function', typeof x);
|
| })(1);
|
|
|
| -assertThrows(function notInDefaultScope(x = y) {
|
| +// Hoisting is not affected by other complex parameters
|
| +(function irrelevantComplexParameterBinds([y] = [], z) {
|
| + assertEquals(undefined, x);
|
| {
|
| - function y() {}
|
| + function x() {}
|
| + }
|
| + assertEquals('function', typeof x);
|
| +})();
|
| +
|
| +// Hoisting is not affected by rest parameters
|
| +(function irrelevantRestParameterBinds(y, ...z) {
|
| + assertEquals(undefined, x);
|
| + {
|
| + function x() {}
|
| + }
|
| + assertEquals('function', typeof x);
|
| +})();
|
| +
|
| +// Hoisting is not affected by complex rest parameters
|
| +(function irrelevantRestParameterBinds(y, ...[z]) {
|
| + assertEquals(undefined, x);
|
| + {
|
| + function x() {}
|
| }
|
| - assertEquals('function', typeof y);
|
| - assertEquals(x, undefined);
|
| -}, ReferenceError);
|
| + assertEquals('function', typeof x);
|
| +})();
|
| +
|
| +
|
| +// Test that shadowing function name is fine
|
| +{
|
| + let called = false;
|
| + (function shadowFunctionName() {
|
| + if (called) assertUnreachable();
|
| + called = true;
|
| + {
|
| + function shadowFunctionName() {
|
| + return 0;
|
| + }
|
| + assertEquals(0, shadowFunctionName());
|
| + }
|
| + assertEquals(0, shadowFunctionName());
|
| + })();
|
| +}
|
| +
|
| +{
|
| + let called = false;
|
| + (function shadowFunctionNameWithComplexParameter(...r) {
|
| + if (called) assertUnreachable();
|
| + called = true;
|
| + {
|
| + function shadowFunctionNameWithComplexParameter() {
|
| + return 0;
|
| + }
|
| + assertEquals(0, shadowFunctionNameWithComplexParameter());
|
| + }
|
| + assertEquals(0, shadowFunctionNameWithComplexParameter());
|
| + })();
|
| +}
|
| +
|
| +(function shadowOuterVariable() {
|
| + {
|
| + let f = 0;
|
| + (function () {
|
| + assertEquals(undefined, f);
|
| + {
|
| + assertEquals(1, f());
|
| + function f() { return 1; }
|
| + assertEquals(1, f());
|
| + }
|
| + assertEquals(1, f());
|
| + })();
|
| + assertEquals(0, f);
|
| + }
|
| +})();
|
| +
|
| +(function notInDefaultScope() {
|
| + var y = 1;
|
| + (function innerNotInDefaultScope(x = y) {
|
| + assertEquals('undefined', typeof y);
|
| + {
|
| + function y() {}
|
| + }
|
| + assertEquals('function', typeof y);
|
| + assertEquals(1, x);
|
| + })();
|
| +})();
|
| +
|
| +(function noHoistingThroughNestedLexical() {
|
| + {
|
| + let f = 2;
|
| + {
|
| + let y = 3;
|
| + function f() {
|
| + y = 2;
|
| + }
|
| + f();
|
| + assertEquals(2, y);
|
| + }
|
| + assertEquals(2, f);
|
| + }
|
| + assertThrows(()=>f, ReferenceError);
|
| +})();
|
| +
|
| +// Only the first function is hoisted; the second is blocked by the first.
|
| +// Contrast overridingLocalFunction, in which the outer function declaration
|
| +// is not lexical and so the inner declaration is hoisted.
|
| +(function noHoistingThroughNestedFunctions() {
|
| + assertEquals(undefined, f); // Also checks that the var-binding exists
|
| +
|
| + {
|
| + assertEquals(4, f());
|
| +
|
| + function f() {
|
| + return 4;
|
| + }
|
| +
|
| + {
|
| + assertEquals(5, f());
|
| + function f() {
|
| + return 5;
|
| + }
|
| + assertEquals(5, f());
|
| + }
|
| +
|
| + assertEquals(4, f());
|
| + }
|
| +
|
| + assertEquals(4, f());
|
| +})();
|
|
|
| // Test that hoisting from blocks does happen in global scope
|
| function globalHoisted() { return 0; }
|
|
|