@linaria/utils
Advanced tools
Comparing version 4.2.3 to 4.2.4
@@ -83,23 +83,40 @@ /* eslint-disable no-restricted-syntax */ | ||
const deletingNodes = new WeakSet(); | ||
export function findParentForDelete(path) { | ||
const isEmptyList = list => list.length === 0 || list.every(i => deletingNodes.has(i)); | ||
const getPathFromAction = action => { | ||
if (!Array.isArray(action)) { | ||
return action; | ||
} | ||
if (action[0] === 'replace' || action[0] === 'remove') { | ||
return action[1]; | ||
} | ||
throw new Error(`Unknown action type: ${action[0]}`); | ||
}; | ||
export function findActionForNode(path) { | ||
if (isRemoved(path)) return null; | ||
deletingNodes.add(path); | ||
const parent = path.parentPath; | ||
if (!parent) return path; | ||
if (!parent) return ['remove', path]; | ||
if (parent.isProgram()) { | ||
// Do not delete Program node | ||
return path; | ||
return ['remove', path]; | ||
} | ||
if (parent.isFunction() && path.listKey === 'params') { | ||
// Do not remove params of functions | ||
return null; | ||
} | ||
if (parent.isLogicalExpression({ | ||
operator: '&&' | ||
})) { | ||
mutate(parent, p => { | ||
p.replaceWith({ | ||
type: 'BooleanLiteral', | ||
value: false | ||
}); | ||
}); | ||
return null; | ||
return ['replace', parent, { | ||
type: 'BooleanLiteral', | ||
value: false | ||
}]; | ||
} | ||
@@ -117,25 +134,22 @@ | ||
if (maybeDefineProperty?.isCallExpression() && maybeDefineProperty.get('callee').matchesPattern('Object.defineProperty')) { | ||
return findParentForDelete(maybeDefineProperty); | ||
return findActionForNode(maybeDefineProperty); | ||
} | ||
} | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isTemplateLiteral()) { | ||
mutate(path, p => { | ||
p.replaceWith({ | ||
type: 'StringLiteral', | ||
value: '' | ||
}); | ||
}); | ||
return null; | ||
return ['replace', path, { | ||
type: 'StringLiteral', | ||
value: '' | ||
}]; | ||
} | ||
if (parent.isAssignmentExpression()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isCallExpression()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -146,3 +160,3 @@ | ||
})) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -153,3 +167,3 @@ | ||
}) || parent.isFunctionDeclaration() || parent.isObjectMethod() || parent.isClassMethod()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -160,4 +174,4 @@ | ||
if (body.length === 1) { | ||
return findParentForDelete(parent); | ||
if (isEmptyList(body)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -172,3 +186,3 @@ | ||
// It's `if (…) return …`, we can remove it. | ||
return findParentForDelete(prevStatement); | ||
return findActionForNode(prevStatement); | ||
} | ||
@@ -178,3 +192,3 @@ } else if (body.slice(1).every(statement => deletingNodes.has(statement))) { | ||
// are marked for deletion, we can remove the whole block. | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -185,7 +199,7 @@ } | ||
if (parent.isVariableDeclarator()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isExportNamedDeclaration() && (parent.node.specifiers.length === 1 && parent.node.specifiers[0] === path.node || parent.node.declaration === path.node)) { | ||
return findParentForDelete(parent); | ||
if (parent.isExportNamedDeclaration() && (path.key === 'specifiers' && isEmptyList(parent.get('specifiers')) || path.key === 'declaration' && parent.node.declaration === path.node)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -197,4 +211,4 @@ | ||
if (list.length === 1) { | ||
return findParentForDelete(parent); | ||
if (isEmptyList(list)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -205,3 +219,3 @@ } | ||
if (parent.isTryStatement()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -214,3 +228,3 @@ | ||
// The parent node isn't valid without this field, so we should remove it also. | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -221,7 +235,7 @@ } | ||
if (path.key === key && parent.get(key) === path) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
} | ||
return path; | ||
return ['remove', path]; | ||
} // @babel/preset-typescript transpiles enums, but doesn't reference used identifiers. | ||
@@ -270,3 +284,3 @@ | ||
const forDeleting = [binding.path, ...binding.constantViolations].map(i => findParentForDelete(i)).filter(isNotNull); | ||
const forDeleting = [binding.path, ...binding.constantViolations].map(findActionForNode).filter(isNotNull).map(getPathFromAction); | ||
if (forDeleting.length === 0) return; | ||
@@ -294,20 +308,20 @@ findIdentifiers(forDeleting).forEach(identifier => { | ||
let clean = false; | ||
let referencedIdentifiers = []; | ||
const declared = []; | ||
paths.forEach(path => { | ||
const deletingPath = findParentForDelete(path); | ||
if (!deletingPath) return; | ||
referencedIdentifiers.push(...findIdentifiers([deletingPath], 'referenced')); | ||
declared.push(...findIdentifiers([deletingPath], 'binding').map(i => getScope(i).getBinding(i.node.name))); | ||
mutate(deletingPath, p => { | ||
if (!isRemoved(p)) p.remove(); | ||
const actions = paths.map(findActionForNode).filter(isNotNull); | ||
const affectedPaths = actions.map(getPathFromAction); | ||
let referencedIdentifiers = findIdentifiers(affectedPaths, 'referenced'); | ||
const referencesOfBinding = findIdentifiers(affectedPaths, 'binding').map(i => (i.node && getScope(i).getBinding(i.node.name)) ?? null).filter(isNotNull).reduce((acc, i) => [...acc, ...i.referencePaths.filter(nonType)], []); | ||
actions.forEach(action => { | ||
mutate(action[1], p => { | ||
if (isRemoved(p)) return; | ||
if (action[0] === 'remove') { | ||
p.remove(); | ||
} else if (action[0] === 'replace') { | ||
p.replaceWith(action[2]); | ||
} | ||
}); | ||
}); | ||
if (declared.length > 0) { | ||
removeWithRelated(declared.reduce((acc, i) => [...acc, ...i.referencePaths.filter(nonType)], [])); | ||
} | ||
removeWithRelated(referencesOfBinding); | ||
referencedIdentifiers.sort((a, b) => a.node?.name.localeCompare(b.node?.name)); | ||
let clean = false; | ||
@@ -314,0 +328,0 @@ while (!clean && referencedIdentifiers.length > 0) { |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.dereference = dereference; | ||
exports.findParentForDelete = findParentForDelete; | ||
exports.findActionForNode = findActionForNode; | ||
exports.mutate = mutate; | ||
@@ -108,23 +108,39 @@ exports.reference = reference; | ||
function findParentForDelete(path) { | ||
const isEmptyList = list => list.length === 0 || list.every(i => deletingNodes.has(i)); | ||
const getPathFromAction = action => { | ||
if (!Array.isArray(action)) { | ||
return action; | ||
} | ||
if (action[0] === 'replace' || action[0] === 'remove') { | ||
return action[1]; | ||
} | ||
throw new Error(`Unknown action type: ${action[0]}`); | ||
}; | ||
function findActionForNode(path) { | ||
if ((0, _isRemoved.default)(path)) return null; | ||
deletingNodes.add(path); | ||
const parent = path.parentPath; | ||
if (!parent) return path; | ||
if (!parent) return ['remove', path]; | ||
if (parent.isProgram()) { | ||
// Do not delete Program node | ||
return path; | ||
return ['remove', path]; | ||
} | ||
if (parent.isFunction() && path.listKey === 'params') { | ||
// Do not remove params of functions | ||
return null; | ||
} | ||
if (parent.isLogicalExpression({ | ||
operator: '&&' | ||
})) { | ||
mutate(parent, p => { | ||
p.replaceWith({ | ||
type: 'BooleanLiteral', | ||
value: false | ||
}); | ||
}); | ||
return null; | ||
return ['replace', parent, { | ||
type: 'BooleanLiteral', | ||
value: false | ||
}]; | ||
} | ||
@@ -142,25 +158,22 @@ | ||
if (maybeDefineProperty !== null && maybeDefineProperty !== void 0 && maybeDefineProperty.isCallExpression() && maybeDefineProperty.get('callee').matchesPattern('Object.defineProperty')) { | ||
return findParentForDelete(maybeDefineProperty); | ||
return findActionForNode(maybeDefineProperty); | ||
} | ||
} | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isTemplateLiteral()) { | ||
mutate(path, p => { | ||
p.replaceWith({ | ||
type: 'StringLiteral', | ||
value: '' | ||
}); | ||
}); | ||
return null; | ||
return ['replace', path, { | ||
type: 'StringLiteral', | ||
value: '' | ||
}]; | ||
} | ||
if (parent.isAssignmentExpression()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isCallExpression()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -171,3 +184,3 @@ | ||
})) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -178,3 +191,3 @@ | ||
}) || parent.isFunctionDeclaration() || parent.isObjectMethod() || parent.isClassMethod()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -185,4 +198,4 @@ | ||
if (body.length === 1) { | ||
return findParentForDelete(parent); | ||
if (isEmptyList(body)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -197,3 +210,3 @@ | ||
// It's `if (…) return …`, we can remove it. | ||
return findParentForDelete(prevStatement); | ||
return findActionForNode(prevStatement); | ||
} | ||
@@ -203,3 +216,3 @@ } else if (body.slice(1).every(statement => deletingNodes.has(statement))) { | ||
// are marked for deletion, we can remove the whole block. | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -210,7 +223,7 @@ } | ||
if (parent.isVariableDeclarator()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
if (parent.isExportNamedDeclaration() && (parent.node.specifiers.length === 1 && parent.node.specifiers[0] === path.node || parent.node.declaration === path.node)) { | ||
return findParentForDelete(parent); | ||
if (parent.isExportNamedDeclaration() && (path.key === 'specifiers' && isEmptyList(parent.get('specifiers')) || path.key === 'declaration' && parent.node.declaration === path.node)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -222,4 +235,4 @@ | ||
if (list.length === 1) { | ||
return findParentForDelete(parent); | ||
if (isEmptyList(list)) { | ||
return findActionForNode(parent); | ||
} | ||
@@ -230,3 +243,3 @@ } | ||
if (parent.isTryStatement()) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -239,3 +252,3 @@ | ||
// The parent node isn't valid without this field, so we should remove it also. | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
@@ -246,7 +259,7 @@ } | ||
if (path.key === key && parent.get(key) === path) { | ||
return findParentForDelete(parent); | ||
return findActionForNode(parent); | ||
} | ||
} | ||
return path; | ||
return ['remove', path]; | ||
} // @babel/preset-typescript transpiles enums, but doesn't reference used identifiers. | ||
@@ -296,3 +309,3 @@ | ||
const forDeleting = [binding.path, ...binding.constantViolations].map(i => findParentForDelete(i)).filter(_isNotNull.default); | ||
const forDeleting = [binding.path, ...binding.constantViolations].map(findActionForNode).filter(_isNotNull.default).map(getPathFromAction); | ||
if (forDeleting.length === 0) return; | ||
@@ -324,19 +337,22 @@ (0, _findIdentifiers.default)(forDeleting).forEach(identifier => { | ||
let clean = false; | ||
let referencedIdentifiers = []; | ||
const declared = []; | ||
paths.forEach(path => { | ||
const deletingPath = findParentForDelete(path); | ||
if (!deletingPath) return; | ||
referencedIdentifiers.push(...(0, _findIdentifiers.default)([deletingPath], 'referenced')); | ||
declared.push(...(0, _findIdentifiers.default)([deletingPath], 'binding').map(i => (0, _getScope.getScope)(i).getBinding(i.node.name))); | ||
mutate(deletingPath, p => { | ||
if (!(0, _isRemoved.default)(p)) p.remove(); | ||
const actions = paths.map(findActionForNode).filter(_isNotNull.default); | ||
const affectedPaths = actions.map(getPathFromAction); | ||
let referencedIdentifiers = (0, _findIdentifiers.default)(affectedPaths, 'referenced'); | ||
const referencesOfBinding = (0, _findIdentifiers.default)(affectedPaths, 'binding').map(i => { | ||
var _ref; | ||
return (_ref = i.node && (0, _getScope.getScope)(i).getBinding(i.node.name)) !== null && _ref !== void 0 ? _ref : null; | ||
}).filter(_isNotNull.default).reduce((acc, i) => [...acc, ...i.referencePaths.filter(_findIdentifiers.nonType)], []); | ||
actions.forEach(action => { | ||
mutate(action[1], p => { | ||
if ((0, _isRemoved.default)(p)) return; | ||
if (action[0] === 'remove') { | ||
p.remove(); | ||
} else if (action[0] === 'replace') { | ||
p.replaceWith(action[2]); | ||
} | ||
}); | ||
}); | ||
if (declared.length > 0) { | ||
removeWithRelated(declared.reduce((acc, i) => [...acc, ...i.referencePaths.filter(_findIdentifiers.nonType)], [])); | ||
} | ||
removeWithRelated(referencesOfBinding); | ||
referencedIdentifiers.sort((a, b) => { | ||
@@ -347,2 +363,3 @@ var _a$node2, _b$node2; | ||
}); | ||
let clean = false; | ||
@@ -349,0 +366,0 @@ while (!clean && referencedIdentifiers.length > 0) { |
{ | ||
"name": "@linaria/utils", | ||
"description": "Blazing fast zero-runtime CSS in JS library", | ||
"version": "4.2.3", | ||
"version": "4.2.4", | ||
"bugs": "https://github.com/callstack/linaria/issues", | ||
@@ -6,0 +6,0 @@ "dependencies": { |
import type { Binding, NodePath } from '@babel/traverse'; | ||
import type { Identifier, JSXIdentifier } from '@babel/types'; | ||
import type { Node, Identifier, JSXIdentifier } from '@babel/types'; | ||
export declare function reference(path: NodePath<Identifier | JSXIdentifier>, referencePath?: NodePath, force?: boolean): void; | ||
export declare function dereference(path: NodePath<Identifier | JSXIdentifier>): Binding | null; | ||
export declare function referenceAll(path: NodePath): void; | ||
export declare function findParentForDelete(path: NodePath): NodePath | null; | ||
declare type ReplaceAction = [action: 'replace', what: NodePath, by: Node]; | ||
declare type RemoveAction = [action: 'remove', what: NodePath]; | ||
export declare function findActionForNode(path: NodePath): RemoveAction | ReplaceAction | null; | ||
declare function removeWithRelated(paths: NodePath[]): void; | ||
declare function mutate<T extends NodePath>(path: T, fn: (p: T) => NodePath[] | void): void; | ||
export { mutate, removeWithRelated }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
363452
3725