prohibit let/const redeclaration (#2277)

fixes #2270
This commit is contained in:
Alex Lam S.L
2017-08-14 12:31:12 +08:00
committed by GitHub
parent 2bf8216e50
commit a5461e0adc
5 changed files with 63 additions and 18 deletions

View File

@@ -203,6 +203,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|| node instanceof AST_SymbolLet
|| node instanceof AST_SymbolConst) {
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node);
if (!all(def.orig, function(sym) {
if (sym === node) return true;
if (node instanceof AST_SymbolBlockDeclaration) {
return sym instanceof AST_SymbolLambda;
}
return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst);
})) {
js_error(
node.name + " redeclared",
node.start.file,
node.start.line,
node.start.col,
node.start.pos
);
}
if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
def.destructuring = in_destructuring;
if (defun !== scope) {
@@ -357,7 +372,7 @@ AST_IterationStatement.DEFMETHOD("is_block_scope", return_true);
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
this.uses_arguments = false;
this.def_variable(new AST_SymbolConst({
this.def_variable(new AST_SymbolFunarg({
name: "arguments",
start: this.start,
end: this.end

View File

@@ -65,10 +65,10 @@ nested_destructuring_objects: {
}
input: {
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
let [{d},e] = f;
var [{g},h] = i;
}
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
expect_exact: 'const[{a},b]=c;let[{d},e]=f;var[{g},h]=i;';
}
destructuring_constdef_in_loops: {
@@ -274,8 +274,8 @@ reduce_vars: {
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
let [{d},e] = f;
var [{g},h] = i;
[{a},b] = c;
for (const [x,y] in pairs);
for (let [x,y] in pairs);
@@ -292,8 +292,8 @@ reduce_vars: {
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
const [{a},b] = c;
let [{a},b] = c;
var [{a},b] = c;
let [{d},e] = f;
var [{g},h] = i;
[{a},b] = c;
for (const [x,y] in pairs);
for (let [x,y] in pairs);

View File

@@ -211,13 +211,13 @@ export_statement: {
}
input: {
export default 1 + 2;
export var foo = 4;
export let foo = 6;
export const foo = 6;
export function foo() {};
export class foo { };
export var a = 4;
export let b = 6;
export const c = 6;
export function d() {};
export class e {};
}
expect_exact: "export default 3;export var foo=4;export let foo=6;export const foo=6;export function foo(){};export class foo{};"
expect_exact: "export default 3;export var a=4;export let b=6;export const c=6;export function d(){};export class e{};"
}
export_default_object_expression: {

View File

@@ -142,11 +142,11 @@ destructuring_arguments_3: {
}
input: {
function fn3({x: {y: {z: {} = 42}}}) {}
const { cover = (function () {}), xCover = (0, function() {}) } = {};
let { cover = (function () {}), xCover = (0, function() {}) } = {};
var { cover = (function () {}), xCover = (0, function() {}) } = {};
const { a = (function () {}), b = (0, function() {}) } = {};
let { c = (function () {}), d = (0, function() {}) } = {};
var { e = (function () {}), f = (0, function() {}) } = {};
}
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{cover=function(){},xCover=(0,function(){})}={};let{cover=function(){},xCover=(0,function(){})}={};var{cover=function(){},xCover=(0,function(){})}={};"
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{a=function(){},b=(0,function(){})}={};let{c=function(){},d=(0,function(){})}={};var{e=function(){},f=(0,function(){})}={};"
}
default_arguments: {

View File

@@ -291,4 +291,34 @@ describe("minify", function() {
assert.strictEqual(result.code, "alert({bar:42});");
});
});
describe("duplicated block-scoped declarations", function() {
[
"let a=1;let a=2;",
"let a=1;var a=2;",
"var a=1;let a=2;",
"let[a]=[1];var a=2;",
"let a=1;var[a]=[2];",
"let[a]=[1];var[a]=[2];",
"const a=1;const a=2;",
"const a=1;var a=2;",
"var a=1;const a=2;",
"const[a]=[1];var a=2;",
"const a=1;var[a]=[2];",
"const[a]=[1];var[a]=[2];",
].forEach(function(code) {
it(code, function() {
var result = Uglify.minify(code, {
compress: false,
mangle: false
});
assert.strictEqual(result.error, undefined);
assert.strictEqual(result.code, code);
result = Uglify.minify(code);
var err = result.error;
assert.ok(err instanceof Error);
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: a redeclared");
});
});
});
});