Bug 1198833 - Variable redeclaration should be a syntax error r=shu

This commit is contained in:
Jon Coppeard
2015-12-15 13:36:14 +00:00
committed by Cameron Kaiser
parent 7171345691
commit ac6710b0fd
12 changed files with 23 additions and 39 deletions

View File

@@ -1,4 +1,4 @@
// |jit-test| error: TypeError // |jit-test| error: SyntaxError
{ {
const x = 0; const x = 0;
function x() { } function x() { }

View File

@@ -1,3 +1,3 @@
// |jit-test| error: TypeError // |jit-test| error: SyntaxError
const x = 0; const x = 0;
function x() { } function x() { }

View File

@@ -1,4 +1,4 @@
// |jit-test| error: TypeError // |jit-test| error: SyntaxError
{ {
let x; let x;
function x() { } function x() { }

View File

@@ -1,3 +1,3 @@
// |jit-test| error: TypeError // |jit-test| error: SyntaxError
s = newGlobal(); s = newGlobal();
evalcx("let NaN = 0;", s); evalcx("let NaN = 0;", s);

View File

@@ -1,4 +1,4 @@
// |jit-test| error: TypeError // |jit-test| error: SyntaxError
var hits = 0; var hits = 0;
with(f_arg => constructor.f_arg([3, 4, 5], null)) var length = 257751; with(f_arg => constructor.f_arg([3, 4, 5], null)) var length = 257751;

View File

@@ -6,19 +6,8 @@ function testNoError(source) {
parseModule(source); parseModule(source);
} }
function testParseError(source, expectedError) {
print(source);
assertThrowsInstanceOf(function () {
parseModule(source);
}, expectedError);
}
function testSyntaxError(source) { function testSyntaxError(source) {
testParseError(source, SyntaxError); assertThrowsInstanceOf(() => parseModule(source), SyntaxError);
}
function testTypeError(source) {
testParseError(source, TypeError);
} }
testNoError("import { a } from 'm';"); testNoError("import { a } from 'm';");
@@ -26,15 +15,13 @@ testNoError("import { a as b } from 'm';");
testNoError("import * as a from 'm';"); testNoError("import * as a from 'm';");
testNoError("import a from 'm';"); testNoError("import a from 'm';");
// TODO: The spec says redeclaration is a syntax error but we report it as a testSyntaxError("import { a } from 'm'; let a = 1;");
// type error. testSyntaxError("let a = 1; import { a } from 'm';");
testTypeError("import { a } from 'm'; let a = 1;"); testSyntaxError("import { a } from 'm'; var a = 1;");
testTypeError("let a = 1; import { a } from 'm';"); testSyntaxError("var a = 1; import { a } from 'm';");
testTypeError("import { a } from 'm'; var a = 1;"); testSyntaxError("import { a, b } from 'm'; const b = 1;");
testTypeError("var a = 1; import { a } from 'm';"); testSyntaxError("import { a } from 'm'; import { a } from 'm2';");
testTypeError("import { a, b } from 'm'; const b = 1;"); testSyntaxError("import { a } from 'm'; import { b as a } from 'm2';");
testTypeError("import { a } from 'm'; import { a } from 'm2';"); testSyntaxError("import { a } from 'm'; import * as a from 'm2';");
testTypeError("import { a } from 'm'; import { b as a } from 'm2';"); testSyntaxError("import { a } from 'm'; import a from 'm2';");
testTypeError("import { a } from 'm'; import * as a from 'm2';");
testTypeError("import { a } from 'm'; import a from 'm2';");

View File

@@ -63,7 +63,7 @@ MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due t
MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key")
MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage")
MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length")
MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}") MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}")
MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}")
MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter") MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter")
MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}")

View File

@@ -28,7 +28,7 @@ evaluate("const globalConstant = 0; var earlyError = true;");
try { try {
evaluate("earlyError = false; class globalConstant { constructor() { } }"); evaluate("earlyError = false; class globalConstant { constructor() { } }");
} catch (e if e instanceof TypeError) { } } catch (e if e instanceof SyntaxError) { }
assertEq(earlyError, true); assertEq(earlyError, true);
function strictEvalShadows() { function strictEvalShadows() {

View File

@@ -51,10 +51,7 @@ isOK("for (let x = 5, y; ; ) ;");
isOK("for (let [z] = [3]; ; ) ;"); isOK("for (let [z] = [3]; ; ) ;");
isError("for (let [z, z]; ; ) ;", SyntaxError); // because missing initializer isError("for (let [z, z]; ; ) ;", SyntaxError); // because missing initializer
// This is wrong! Per 13.2.1.1, "It is a Syntax Error if the BoundNames of isError("for (let [z, z] = [0, 1]; ; ) ;", SyntaxError);
// BindingList contains any duplicate entries." But we don't implement this
// yet, so it becomes a TypeError at runtime.
isError("for (let [z, z] = [0, 1]; ; ) ;", TypeError);
// A for-loop with lexical declarations, with a mixture of bindings that are and // A for-loop with lexical declarations, with a mixture of bindings that are and
// aren't aliased. (The mixture stress-tests any code that incorrectly assumes // aren't aliased. (The mixture stress-tests any code that incorrectly assumes

View File

@@ -21,7 +21,7 @@ function test()
printBugNumber(BUGNUMBER); printBugNumber(BUGNUMBER);
printStatus (summary); printStatus (summary);
expect = 'TypeError: redeclaration of var e'; expect = 'SyntaxError: redeclaration of var e';
try try
{ {
eval('{ var e = 3; let e = ""; } print(typeof e);'); eval('{ var e = 3; let e = ""; } print(typeof e);');

View File

@@ -32,7 +32,7 @@ function test()
} }
reportCompare(expect, actual, summary); reportCompare(expect, actual, summary);
expect = 'TypeError: redeclaration of let x'; expect = 'SyntaxError: redeclaration of let x';
try try
{ {
eval('{ let x; {var x;} }'); eval('{ let x; {var x;} }');

View File

@@ -199,15 +199,15 @@ function testClasses() {
// Class statements bind lexically, so they should collide with other // Class statements bind lexically, so they should collide with other
// in-block lexical bindings, but class expressions don't. // in-block lexical bindings, but class expressions don't.
let FooCtor = ctorWithName("Foo"); let FooCtor = ctorWithName("Foo");
assertError("{ let Foo; class Foo { constructor() { } } }", TypeError); assertError("{ let Foo; class Foo { constructor() { } } }", SyntaxError);
assertStmt("{ let Foo; (class Foo { constructor() { } }) }", assertStmt("{ let Foo; (class Foo { constructor() { } }) }",
blockStmt([letDecl([{id: ident("Foo"), init: null}]), blockStmt([letDecl([{id: ident("Foo"), init: null}]),
exprStmt(classExpr(ident("Foo"), null, [FooCtor]))])); exprStmt(classExpr(ident("Foo"), null, [FooCtor]))]));
assertError("{ const Foo = 0; class Foo { constructor() { } } }", TypeError); assertError("{ const Foo = 0; class Foo { constructor() { } } }", SyntaxError);
assertStmt("{ const Foo = 0; (class Foo { constructor() { } }) }", assertStmt("{ const Foo = 0; (class Foo { constructor() { } }) }",
blockStmt([constDecl([{id: ident("Foo"), init: lit(0)}]), blockStmt([constDecl([{id: ident("Foo"), init: lit(0)}]),
exprStmt(classExpr(ident("Foo"), null, [FooCtor]))])); exprStmt(classExpr(ident("Foo"), null, [FooCtor]))]));
assertError("{ class Foo { constructor() { } } class Foo { constructor() { } } }", TypeError); assertError("{ class Foo { constructor() { } } class Foo { constructor() { } } }", SyntaxError);
assertStmt(`{ assertStmt(`{
(class Foo { (class Foo {
constructor() { } constructor() { }