Correctly eliminate destructuring assignment (#13144)

This eliminates code referenced via destructuring assignment, as reported by @styfle.
This commit is contained in:
Joe Haddad 2020-05-20 11:57:18 -04:00 committed by GitHub
parent e28ce34ccb
commit 92a159d939
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 13 deletions

View file

@ -189,13 +189,33 @@ export default function nextTransformSsg({
path.traverse(
{
VariableDeclarator(path, state) {
if (path.node.id.type !== 'Identifier') {
return
}
if (path.node.id.type === 'Identifier') {
const local = path.get('id') as NodePath<
BabelTypes.Identifier
>
if (isIdentifierReferenced(local)) {
state.refs.add(local)
}
} else if (path.node.id.type === 'ObjectPattern') {
const pattern = path.get('id') as NodePath<
BabelTypes.ObjectPattern
>
const local = path.get('id') as NodePath<BabelTypes.Identifier>
if (isIdentifierReferenced(local)) {
state.refs.add(local)
const properties = pattern.get('properties')
properties.forEach((p) => {
const local = p.get(
p.node.type === 'ObjectProperty'
? 'value'
: p.node.type === 'RestElement'
? 'argument'
: (function () {
throw new Error('invariant')
})()
) as NodePath<BabelTypes.Identifier>
if (isIdentifierReferenced(local)) {
state.refs.add(local)
}
})
}
},
FunctionDeclaration: markFunction,
@ -319,14 +339,44 @@ export default function nextTransformSsg({
path.traverse({
// eslint-disable-next-line no-loop-func
VariableDeclarator(path) {
if (path.node.id.type !== 'Identifier') {
return
}
if (path.node.id.type === 'Identifier') {
const local = path.get('id') as NodePath<
BabelTypes.Identifier
>
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count
path.remove()
}
} else if (path.node.id.type === 'ObjectPattern') {
const pattern = path.get('id') as NodePath<
BabelTypes.ObjectPattern
>
const local = path.get('id') as NodePath<BabelTypes.Identifier>
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count
path.remove()
const beforeCount = count
const properties = pattern.get('properties')
properties.forEach((p) => {
const local = p.get(
p.node.type === 'ObjectProperty'
? 'value'
: p.node.type === 'RestElement'
? 'argument'
: (function () {
throw new Error('invariant')
})()
) as NodePath<BabelTypes.Identifier>
if (refs.has(local) && !isIdentifierReferenced(local)) {
++count
p.remove()
}
})
if (
beforeCount !== count &&
pattern.get('properties').length < 1
) {
path.remove()
}
}
},
FunctionDeclaration: sweepFunction,

View file

@ -452,5 +452,29 @@ describe('babel plugin (next-ssg-transform)', () => {
`"export var __N_SSG=true;export default function Home(){return __jsx(\\"div\\",null);}"`
)
})
it('destructuring assignment (object)', () => {
const output = babel(trim`
import fs from 'fs';
import other from 'other';
const {readFile, readdir, access: foo} = fs.promises;
const {a,b, cat: bar,...rem} = other;
export async function getStaticProps() {
readFile;
readdir;
foo;
b;
cat;
rem;
}
export default function Home() { return <div />; }
`)
expect(output).toMatchInlineSnapshot(
`"import other from'other';const{a,cat:bar}=other;export var __N_SSG=true;export default function Home(){return __jsx(\\"div\\",null);}"`
)
})
})
})