//------------------------------------------------------------------------------------------------------- | |
// Copyright (C) Microsoft. All rights reserved. | |
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | |
//------------------------------------------------------------------------------------------------------- | |
// ES6 block-scoping with closures, switches | |
var x = 'global x'; | |
function write(x) { WScript.Echo(x); } | |
(function() { | |
try { | |
inner(); | |
} | |
catch(e) { | |
write(e); | |
} | |
let x = 'local x'; | |
try { | |
inner(); | |
} | |
catch(e) { | |
write(e); | |
} | |
function inner() { | |
write(x); | |
} | |
})(); | |
(function() { | |
while(1) { | |
try { | |
LABEL0: | |
switch(x) { | |
case 0: | |
let x = 'local x'; | |
// fall through | |
default: | |
function inner() { | |
write(x); | |
} | |
inner(); | |
// Should only get here after executing case 0. | |
return; | |
case 'seriously?': | |
break LABEL0; | |
} | |
} | |
catch(e) { | |
write(e); | |
// Should assign to global x. | |
x = 0; | |
} | |
} | |
})(); | |
try { | |
(function() { | |
if (typeof a === 'string') { | |
write('a is a string'); | |
} | |
let a = 'let a'; | |
})(); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
(function() { | |
let a = 'let a'; | |
if (typeof a === 'string') { | |
write('a is a string'); | |
} | |
})(); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
(function () { | |
if (delete a) { | |
write("deleted a"); | |
} else { | |
write("did not delete a"); | |
} | |
let a = 'let a'; | |
})(); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
(function () { | |
let a = 'let a'; | |
if (delete a) { | |
write("deleted a"); | |
} else { | |
write("did not delete a"); | |
} | |
})(); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
try { | |
write(eval('typeof t')); | |
} | |
catch(e) { | |
write(e); | |
} | |
(function() { | |
write(eval('typeof t')); | |
})(); | |
} | |
catch(e) { | |
write(e); | |
} | |
let t; | |
write(eval('typeof t')); | |
(function () { | |
try { | |
let foo = eval('foo();'); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
const foo = eval('foo();'); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
eval('foo();'); | |
let foo = 123; | |
} catch (e) { | |
write(e); | |
} | |
try { | |
eval('foo();'); | |
const foo = 123; | |
} catch (e) { | |
write(e); | |
} | |
})(); | |
(function () { | |
try { | |
eval('let a = a;'); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
eval('const a = a;'); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
// this works in a try/catch because Use Before Declaration is always a runtime error by the spec | |
let a = a; | |
} catch (e) { | |
write(e); | |
} | |
try { | |
// this works in a try/catch because Use Before Declaration is always a runtime error by the spec | |
const a = a; | |
} catch (e) { | |
write(e); | |
} | |
})(); | |
(function () { | |
try { | |
eval('a() = 123; let a;'); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
eval('a() = 123; const a = undefined;'); | |
} catch (e) { | |
write(e); | |
} | |
})(); | |
try { | |
write(delete glo_a); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
write(typeof glo_a); | |
} catch (e) { | |
write(e); | |
} | |
let glo_a = 'glo_a'; | |
try { | |
write(delete glo_a); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
write(typeof glo_a); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
write(delete glo_b); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
write(typeof glo_b); | |
} catch (e) { | |
write(e); | |
} | |
const glo_b = 'glo_b'; | |
try { | |
write(delete glo_b); | |
} catch (e) { | |
write(e); | |
} | |
try { | |
write(typeof glo_b); | |
} catch (e) { | |
write(e); | |
} | |
//BLUE 404930 | |
try { | |
switch (Math.round(.2)) { | |
case 3: | |
let x = eval(""); | |
default: | |
x; // should emit a use-before-decl runtime error | |
} | |
} catch (e) { | |
write(e); | |
} | |
// BLUE 404930 (bug reused, different from above) | |
function testStSlotNoThrow() { let y = function () { write(y = 123); }; write(y); y(); write(y); } | |
function testStSlotThrow() { let y = (function () { write(y = 123); })(); write(y); } | |
function testStObjSlotNoThrow() { let y = function () { write(y = 123); }; write(y); y(); write(y); eval('y'); } | |
function testStObjSlotThrow() { let y = (function () { write(y = 123); })(); write(y); eval('y'); } | |
function testTypeOfNoThrow() { let y = function () { write(typeof y); }; y(); } | |
function testTypeOfThrow() { let y = (function () { write(typeof y); })(); } | |
function testTypeOfObjNoThrow() { let y = function () { write(typeof y); }; y(); eval('y'); } | |
function testTypeOfObjThrow() { let y = (function () { write(typeof y); })(); eval('y'); } | |
function testLdSlotNoThrow() { let y = function () { write(y); }; y(); } | |
function testLdSlotThrow() { let y = (function () { write(y); })(); } | |
function testLdObjSlotNoThrow() { let y = function () { write(y); }; y(); eval('y'); } | |
function testLdObjSlotThrow() { let y = (function () { write(y); })(); eval('y'); } | |
try { testStSlotNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testStSlotThrow(); } catch (e) { write(e); } | |
try { testStObjSlotNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testStObjSlotThrow(); } catch (e) { write(e); } | |
try { testTypeOfNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testTypeOfThrow(); } catch (e) { write(e); } | |
try { testTypeOfObjNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testTypeOfObjThrow(); } catch (e) { write(e); } | |
try { testLdSlotNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testLdSlotThrow(); } catch (e) { write(e); } | |
try { testLdObjSlotNoThrow(); } catch (e) { write("shouldn't throw! " + e); } | |
try { testLdObjSlotThrow(); } catch (e) { write(e); } | |
function testBugVsoOs849056() { | |
let x; // this x should get a scope slot | |
function inner() { | |
y = x; // should throw use before declaration | |
let y; | |
} | |
inner(); | |
} | |
try { testBugVsoOs849056(); } catch (e) { write(e); } | |
function testBugVsoOs1141661() { | |
y = 5; | |
let y; | |
eval("write('This should be unreachable');"); | |
} | |
try { testBugVsoOs1141661(); } catch (e) { write(e); } | |