Skip to content

Commit

Permalink
fix: empty destructuring with var should be converted to const
Browse files Browse the repository at this point in the history
  • Loading branch information
pionxzh committed Oct 1, 2023
1 parent bdc8ecc commit 0301a2e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/transform/let.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ export default function(ast, loggerInstance) {
variableMarker.markModified(decl.id.name);
}
});


// Empty destructuring should be converted to const.
//
// var [] = foo;
// var {} = foo;
//
// Mix of empty and non-empty destructuring should be left as is.
if (node.kind === 'var' && node.declarations.every(isEmptyDestructuring)) {
node.kind = 'const';
}
}
else if (node.type === 'AssignmentExpression') {
destructuring.extractVariableNames(node.left).forEach(name => {
Expand Down Expand Up @@ -90,6 +101,16 @@ function isAnyWhileStatement(node) {
node.type === 'DoWhileStatement';
}

function isEmptyDestructuring(node) {
if (node.id.type === 'ObjectPattern') {
return node.id.properties.length === 0;
}
if (node.id.type === 'ArrayPattern') {
return node.id.elements.length === 0;
}
return false;
}

// Program node works almost like a function:
// it hoists all variables which can be transformed to block-scoped let/const.
// It just doesn't have name and parameters.
Expand Down Expand Up @@ -190,7 +211,7 @@ function transformVarsToLetOrConst() {

// let and const declarations aren't allowed in all the same places where
// var declarations are allowed. Notably, only var-declaration can occur
// directlt in if-statement (and other similar statements) body:
// directly in if-statement (and other similar statements) body:
//
// if (true) var x = 10;
//
Expand Down
25 changes: 25 additions & 0 deletions test/transform/letTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ describe('Let/const', () => {
'for (let i=0, len=arr.length; i<len; i++) {}'
);
});

it('should split to let & const when mixed with empty destructuring', () => {
expectTransform(
'var [] = [1, 2], {} = {foo: 1, bar: 2}, x = 1, y = 2;\n' +
'y = 3;'
).toReturn(
'const [] = [1, 2];\n' +
'const {} = {foo: 1, bar: 2};\n' +
'const x = 1;\n' +
'let y = 2;\n' +
'y = 3;'
);
});
});

describe('with variable declaration in restrictive parent', () => {
Expand Down Expand Up @@ -278,6 +291,18 @@ describe('Let/const', () => {
'console.log(x);'
);
});

it('should use const when no variables are destructured', () => {
expectTransform(
'var [] = [1, 2];\n' +
'var {} = {foo: 1, bar: 2};\n' +
'var [] = [1, 2], {} = {foo: 1, bar: 2};'
).toReturn(
'const [] = [1, 2];\n' +
'const {} = {foo: 1, bar: 2};\n' +
'const [] = [1, 2], {} = {foo: 1, bar: 2};'
);
});
});

describe('with nested function', () => {
Expand Down

0 comments on commit 0301a2e

Please sign in to comment.