// Error message for redeclaration should show the position where the variable // was declared. const npos = -1; function test_one(fun, filename, name, [prevLineNumber, prevColumnNumber], [lineNumber, columnNumber]) { let caught = false; try { fun(); } catch (e) { assertEq(e.message.includes("redeclaration"), true); assertEq(e.lineNumber, lineNumber); assertEq(e.columnNumber, columnNumber); let notes = getErrorNotes(e); if (prevLineNumber == npos) { assertEq(notes.length, 0); } else { assertEq(notes.length, 1); let note = notes[0]; assertEq(note.message, `Previously declared at line ${prevLineNumber}, column ${prevColumnNumber}`); assertEq(note.lineNumber, prevLineNumber); assertEq(note.columnNumber, prevColumnNumber); if (filename) assertEq(note.fileName, filename); } caught = true; } assertEq(caught, true); } function test_parse(source, ...args) { test_one(() => { Reflect.parse(source, { source: "foo.js" }); }, "foo.js", ...args); } function test_eval(source, ...args) { test_one(() => { eval(source); }, undefined, ...args); } function test(...args) { test_parse(...args); test_eval(...args); } // let test(` let a, a; `, "a", [2, 4], [2, 7]); test(` let a; let a; `, "a", [2, 4], [3, 4]); test(` let a; const a = 1; `, "a", [2, 4], [3, 6]); test(` let a; var a; `, "a", [2, 4], [3, 4]); test(` let a; function a() { } `, "a", [2, 4], [3, 9]); test(` { let a; function a() { } } `, "a", [3, 6], [4, 11]); // const test(` const a = 1, a = 2; `, "a", [2, 6], [2, 13]); test(` const a = 1; const a = 2; `, "a", [2, 6], [3, 6]); test(` const a = 1; let a; `, "a", [2, 6], [3, 4]); test(` const a = 1; var a; `, "a", [2, 6], [3, 4]); test(` const a = 1; function a() { } `, "a", [2, 6], [3, 9]); test(` { const a = 1; function a() { } } `, "a", [3, 8], [4, 11]); // var test(` var a; let a; `, "a", [2, 4], [3, 4]); test(` var a; const a = 1; `, "a", [2, 4], [3, 6]); // function test(` function a() {}; let a; `, "a", [2, 9], [3, 4]); test(` function a() {}; const a = 1; `, "a", [2, 9], [3, 6]); // Annex B lexical function test(` { function a() {}; let a; } `, "a", [3, 11], [4, 6]); test(` { function a() {}; const a = 1; } `, "a", [3, 11], [4, 8]); // catch parameter test(` try { } catch (a) { let a; } `, "a", [3, 9], [4, 6]); test(` try { } catch (a) { const a = 1; } `, "a", [3, 9], [4, 8]); test(` try { } catch (a) { function a() { } } `, "a", [3, 9], [4, 11]); // parameter test(` function f(a) { let a; } `, "a", [2, 11], [3, 6]); test(` function f(a) { const a = 1; } `, "a", [2, 11], [3, 8]); test(` function f([a]) { let a; } `, "a", [2, 12], [3, 6]); test(` function f({a}) { let a; } `, "a", [2, 12], [3, 6]); test(` function f(...a) { let a; } `, "a", [2, 14], [3, 6]); test(` function f(a=1) { let a; } `, "a", [2, 11], [3, 6]); // eval // We don't have position information at runtime. // No note should be shown. test_eval(` let a; eval("var a"); `, "a", [npos, npos], [1, 4]);