Skip to content

Commit

Permalink
feat(smart-inline): support computed property destructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
pionxzh committed Nov 25, 2023
1 parent 01d2ac9 commit 0e4bdd9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ console.log(x, y, color);
`,
)

inlineTest.only('property destructuring - with string literal and invalid identifier',
`
const t = e['color'];
const n = e['2d'];
e['type'];
console.log(t, n);
`,
`
const {
color,
"2d": _2d,
type
} = e;
console.log(color, _2d);
`,
)

inlineTest('property destructuring - with temp variable inlined',
`
const e = source;
Expand Down
34 changes: 21 additions & 13 deletions packages/unminify/src/transformations/smart-inline.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { findReferences } from '@wakaru/ast-utils'
import { MultiMap } from '@wakaru/ds'
import { mergeComments } from '../utils/comments'
import { generateName } from '../utils/identifier'
import { generateName, isValidIdentifier } from '../utils/identifier'
import { nonNullable } from '../utils/utils'
import wrap from '../wrapAstTransformation'
import type { ASTTransformation } from '../wrapAstTransformation'
Expand Down Expand Up @@ -81,8 +81,8 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
type: 'Identifier',
},
// @ts-expect-error
property: {
type: 'Identifier',
property: (property: MemberExpression['property']) => {
return j.Identifier.check(property) || j.StringLiteral.check(property)
},
},
}],
Expand All @@ -93,13 +93,12 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope

const variableDeclarator = declarations[0] as VariableDeclarator
const init = variableDeclarator.init as MemberExpression
if (init.computed) return

const object = init.object as Identifier
objectAccessDeclarationMap.set(object.name, _node)

const property = init.property as Identifier
variableKindMap.set(property.name, _node.kind)
const propertyName = getMemberPropertyName(j, init)
if (propertyName) variableKindMap.set(propertyName, _node.kind)
}

// Collect all index accesses
Expand All @@ -117,6 +116,7 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
object: {
type: 'Identifier',
},
computed: true,
// @ts-expect-error
property: {
type: 'NumericLiteral',
Expand Down Expand Up @@ -166,14 +166,13 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
type: 'Identifier',
},
// @ts-expect-error
property: {
type: 'Identifier',
property: (property: MemberExpression['property']) => {
return j.Identifier.check(property) || j.StringLiteral.check(property)
},
},
})) {
const _node = node as ExpressionStatement
const expression = _node.expression as MemberExpression
if (expression.computed) return

const object = expression.object as Identifier
objectAccessDeclarationMap.set(object.name, _node)
Expand Down Expand Up @@ -220,9 +219,10 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
const preservedComments: CommentKind[] = []
declarations.forEach((declaration) => {
if (j.ExpressionStatement.check(declaration)) {
const expressionStatement = declaration as ExpressionStatement
const expressionStatement = declaration
const expression = expressionStatement.expression as MemberExpression
const propertyName = (expression.property as Identifier).name
const propertyName = getMemberPropertyName(j, expression)
if (!propertyName) return

const newPropertyName = destructuringPropertyMap.get(propertyName)
|| generateName(propertyName, scope, declaredNames)
Expand All @@ -240,7 +240,9 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope

const variableDeclarator = declaration.declarations[0] as VariableDeclarator
const variableName = (variableDeclarator.id as Identifier).name
const propertyName = ((variableDeclarator.init as MemberExpression).property as Identifier).name
const init = variableDeclarator.init as MemberExpression
const propertyName = getMemberPropertyName(j, init)
if (!propertyName) return

const newPropertyName = destructuringPropertyMap.get(propertyName)
|| generateName(propertyName, scope, declaredNames)
Expand All @@ -265,7 +267,7 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
const properties = [...destructuringPropertyMap.entries()]
.map(([propertyName, newPropertyName]) => {
const property = j.objectProperty(
j.identifier(propertyName),
isValidIdentifier(propertyName) ? j.identifier(propertyName) : j.literal(propertyName),
j.identifier(newPropertyName),
)
property.shorthand = propertyName === newPropertyName
Expand All @@ -282,6 +284,12 @@ function handleDestructuring(j: JSCodeshift, body: StatementKind[], scope: Scope
})
}

function getMemberPropertyName(j: JSCodeshift, member: MemberExpression): string | null {
if (!member.computed && j.Identifier.check(member.property)) return member.property.name
if (member.computed && j.StringLiteral.check(member.property)) return member.property.value
return null
}

/**
* Inline temp variable if it's only used once in variable assignment.
*
Expand Down
2 changes: 2 additions & 0 deletions packages/unminify/src/utils/identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export function generateName(input: string, scope: Scope | null = null, existedN
.replace(/\\+/, '/')
.replace(/^\/+/, '')
.replace(/\/+/, '/')
// leading numbers to _{numbers}
.replace(/^[-0-9]+/, m => `_${m}`)

// take last 2 parts of the path
const candidate = cleanName.split(/\//).slice(-2).join('/')
Expand Down

0 comments on commit 0e4bdd9

Please sign in to comment.