@linaria/shaker
Advanced tools
Comparing version 3.0.0-beta.13 to 3.0.0-beta.14
@@ -6,2 +6,14 @@ # Change Log | ||
# [3.0.0-beta.14](https://github.com/callstack/linaria/compare/v3.0.0-beta.13...v3.0.0-beta.14) (2021-11-05) | ||
### Bug Fixes | ||
* **shaker:** exports/object issue with TS (fixes [#861](https://github.com/callstack/linaria/issues/861)) ([#863](https://github.com/callstack/linaria/issues/863)) ([acdbdfe](https://github.com/callstack/linaria/commit/acdbdfe5be46eee238f83eb41aeb2291b5d9e034)) | ||
* **shaker:** reimplement enums support (fixes [#848](https://github.com/callstack/linaria/issues/848)) ([#853](https://github.com/callstack/linaria/issues/853)) ([8f1d7cb](https://github.com/callstack/linaria/commit/8f1d7cbadb2665fd734bcda42fd1caa6042659f4)) | ||
# [3.0.0-beta.13](https://github.com/callstack/linaria/compare/v3.0.0-beta.12...v3.0.0-beta.13) (2021-09-13) | ||
@@ -8,0 +20,0 @@ |
@@ -157,4 +157,4 @@ import { types as t } from '@babel/core'; | ||
if (parent && action !== 'ignore') { | ||
// Node always depends on its parent | ||
if (parent && action !== 'ignore' && t.isStatement(node)) { | ||
// Statement always depends on its parent | ||
this.graph.addEdge(node, parent); | ||
@@ -161,0 +161,0 @@ } |
@@ -128,5 +128,59 @@ import { types as t } from '@babel/core'; | ||
} | ||
/* | ||
* In some cases (such as enums) babel uses CallExpression for object initializations | ||
* (function (Colors) { | ||
* Colors["BLUE"] = "#27509A"; | ||
* })(Colors || (Colors = {})); | ||
*/ | ||
function isLazyInit(statement) { | ||
const { | ||
expression | ||
} = statement; | ||
if (!t.isCallExpression(expression) || expression.arguments.length !== 1) { | ||
return false; | ||
} | ||
const [arg] = expression.arguments; | ||
if (!t.isLogicalExpression(arg) || arg.operator !== '||') { | ||
return false; | ||
} | ||
const { | ||
left, | ||
right | ||
} = arg; | ||
return t.isIdentifier(left) && t.isAssignmentExpression(right); | ||
} | ||
export const visitors = { | ||
/* | ||
* ExpressionStatement | ||
* This is one of the rare cases when a child defines a dependency on a parent. | ||
* Suppose we have a code like this: | ||
* const fn = () => { | ||
* let a = 2; | ||
* a *= 2; | ||
* return a; | ||
* }; | ||
* | ||
* `a *= 2` here is an ExpressionStatement node which contains an expression AssignmentExpression `a *= 2`. | ||
* The result of AssignmentExpression here depends on the fact of ExpressionStatement execution, | ||
* that's why we need to mark the statement as a dependency of the expression. | ||
* If we don't mark it, it will be cut as a useless statement. | ||
*/ | ||
ExpressionStatement(node) { | ||
this.baseVisit(node); | ||
this.graph.addEdge(node, node.expression); | ||
this.graph.addEdge(node.expression, node); | ||
if (isLazyInit(node)) { | ||
this.graph.addEdge(node.expression.arguments[0].right, node); | ||
} | ||
}, | ||
/* | ||
* FunctionDeclaration | FunctionExpression | ObjectMethod | ArrowFunctionExpression | ClassMethod | ClassPrivateMethod; | ||
@@ -147,2 +201,7 @@ * Functions can be either a statement or an expression. | ||
if (t.isFunctionDeclaration(node) && node.id) { | ||
// `id` is an identifier which depends on the function declaration | ||
this.graph.addEdge(node.id, node); | ||
} | ||
if (t.isFunctionExpression(node) && node.id !== null && node.id !== undefined) { | ||
@@ -159,11 +218,2 @@ // keep function name in expressions like `const a = function a();` | ||
/* | ||
* ExpressionStatement | ||
*/ | ||
ExpressionStatement(node) { | ||
this.baseVisit(node); | ||
this.graph.addEdge(node, node.expression); | ||
this.graph.addEdge(node.expression, node); | ||
}, | ||
/* | ||
* BlockStatement | Program | ||
@@ -336,4 +386,15 @@ * The same situation as in ExpressionStatement: if one of the expressions is required, the block itself is also required. | ||
MemberExpression(node) { | ||
this.baseVisit(node); | ||
if (this.visit(node.object, node, 'object') !== 'ignore') { | ||
this.graph.addEdge(node, node.object); | ||
} | ||
this.context.push('expression'); | ||
if (this.visit(node.property, node, 'property') !== 'ignore') { | ||
this.graph.addEdge(node, node.property); | ||
} | ||
this.context.pop(); | ||
this.graph.addEdge(node.object, node); | ||
if (isIdentifier(node.object, 'exports') && this.scope.getDeclaration(node.object) === ScopeManager.globalExportsIdentifier) { | ||
@@ -384,3 +445,5 @@ // We treat `exports.something` and `exports['something']` as identifiers in the global scope | ||
this.graph.addEdge(node.left, node.right); | ||
this.graph.addEdge(node.left, node.right); // At the same time, the left part doesn't make any sense without the whole expression. | ||
this.graph.addEdge(node.left, node); | ||
}, | ||
@@ -409,5 +472,8 @@ | ||
this.graph.addEdge(node.id, node.init); | ||
} // If a statement is required itself, an id is also required | ||
} // If we want to evaluate the value of a declared identifier, | ||
// we need to evaluate the whole expression. | ||
this.graph.addEdge(node.id, node); // If a statement is required itself, an id is also required | ||
this.graph.addEdge(node, node.id); | ||
@@ -414,0 +480,0 @@ }, |
@@ -174,4 +174,4 @@ "use strict"; | ||
if (parent && action !== 'ignore') { | ||
// Node always depends on its parent | ||
if (parent && action !== 'ignore' && _core.types.isStatement(node)) { | ||
// Statement always depends on its parent | ||
this.graph.addEdge(node, parent); | ||
@@ -178,0 +178,0 @@ } |
@@ -141,5 +141,59 @@ "use strict"; | ||
} | ||
/* | ||
* In some cases (such as enums) babel uses CallExpression for object initializations | ||
* (function (Colors) { | ||
* Colors["BLUE"] = "#27509A"; | ||
* })(Colors || (Colors = {})); | ||
*/ | ||
function isLazyInit(statement) { | ||
const { | ||
expression | ||
} = statement; | ||
if (!_core.types.isCallExpression(expression) || expression.arguments.length !== 1) { | ||
return false; | ||
} | ||
const [arg] = expression.arguments; | ||
if (!_core.types.isLogicalExpression(arg) || arg.operator !== '||') { | ||
return false; | ||
} | ||
const { | ||
left, | ||
right | ||
} = arg; | ||
return _core.types.isIdentifier(left) && _core.types.isAssignmentExpression(right); | ||
} | ||
const visitors = { | ||
/* | ||
* ExpressionStatement | ||
* This is one of the rare cases when a child defines a dependency on a parent. | ||
* Suppose we have a code like this: | ||
* const fn = () => { | ||
* let a = 2; | ||
* a *= 2; | ||
* return a; | ||
* }; | ||
* | ||
* `a *= 2` here is an ExpressionStatement node which contains an expression AssignmentExpression `a *= 2`. | ||
* The result of AssignmentExpression here depends on the fact of ExpressionStatement execution, | ||
* that's why we need to mark the statement as a dependency of the expression. | ||
* If we don't mark it, it will be cut as a useless statement. | ||
*/ | ||
ExpressionStatement(node) { | ||
this.baseVisit(node); | ||
this.graph.addEdge(node, node.expression); | ||
this.graph.addEdge(node.expression, node); | ||
if (isLazyInit(node)) { | ||
this.graph.addEdge(node.expression.arguments[0].right, node); | ||
} | ||
}, | ||
/* | ||
* FunctionDeclaration | FunctionExpression | ObjectMethod | ArrowFunctionExpression | ClassMethod | ClassPrivateMethod; | ||
@@ -160,2 +214,7 @@ * Functions can be either a statement or an expression. | ||
if (_core.types.isFunctionDeclaration(node) && node.id) { | ||
// `id` is an identifier which depends on the function declaration | ||
this.graph.addEdge(node.id, node); | ||
} | ||
if (_core.types.isFunctionExpression(node) && node.id !== null && node.id !== undefined) { | ||
@@ -172,11 +231,2 @@ // keep function name in expressions like `const a = function a();` | ||
/* | ||
* ExpressionStatement | ||
*/ | ||
ExpressionStatement(node) { | ||
this.baseVisit(node); | ||
this.graph.addEdge(node, node.expression); | ||
this.graph.addEdge(node.expression, node); | ||
}, | ||
/* | ||
* BlockStatement | Program | ||
@@ -349,4 +399,15 @@ * The same situation as in ExpressionStatement: if one of the expressions is required, the block itself is also required. | ||
MemberExpression(node) { | ||
this.baseVisit(node); | ||
if (this.visit(node.object, node, 'object') !== 'ignore') { | ||
this.graph.addEdge(node, node.object); | ||
} | ||
this.context.push('expression'); | ||
if (this.visit(node.property, node, 'property') !== 'ignore') { | ||
this.graph.addEdge(node, node.property); | ||
} | ||
this.context.pop(); | ||
this.graph.addEdge(node.object, node); | ||
if (isIdentifier(node.object, 'exports') && this.scope.getDeclaration(node.object) === _scope.default.globalExportsIdentifier) { | ||
@@ -397,3 +458,5 @@ // We treat `exports.something` and `exports['something']` as identifiers in the global scope | ||
this.graph.addEdge(node.left, node.right); | ||
this.graph.addEdge(node.left, node.right); // At the same time, the left part doesn't make any sense without the whole expression. | ||
this.graph.addEdge(node.left, node); | ||
}, | ||
@@ -422,5 +485,8 @@ | ||
this.graph.addEdge(node.id, node.init); | ||
} // If a statement is required itself, an id is also required | ||
} // If we want to evaluate the value of a declared identifier, | ||
// we need to evaluate the whole expression. | ||
this.graph.addEdge(node.id, node); // If a statement is required itself, an id is also required | ||
this.graph.addEdge(node, node.id); | ||
@@ -427,0 +493,0 @@ }, |
{ | ||
"name": "@linaria/shaker", | ||
"version": "3.0.0-beta.13", | ||
"version": "3.0.0-beta.14", | ||
"publishConfig": { | ||
@@ -50,5 +50,5 @@ "access": "public" | ||
"@babel/preset-env": ">=7", | ||
"@linaria/babel-preset": "^3.0.0-beta.13", | ||
"@linaria/babel-preset": "^3.0.0-beta.14", | ||
"@linaria/logger": "^3.0.0-beta.3", | ||
"@linaria/preeval": "^3.0.0-beta.13", | ||
"@linaria/preeval": "^3.0.0-beta.14", | ||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24", | ||
@@ -60,3 +60,3 @@ "ts-invariant": "^0.9.0" | ||
}, | ||
"gitHead": "c49df269ebbbc956d43720b007a92f9f865662c5" | ||
"gitHead": "c0c48c589e959087cc206f701f0ca4d42057a5ca" | ||
} |
import type { Node, VisitorKeys } from '@babel/types'; | ||
import ScopeManager from './scope'; | ||
import DepsGraph from './DepsGraph'; | ||
import { VisitorAction } from './types'; | ||
export declare type OnVisitCallback = (n: Node) => void; | ||
@@ -14,3 +15,3 @@ export default abstract class GraphBuilderState { | ||
abstract baseVisit<TNode extends Node>(node: TNode, ignoreDeps?: boolean): void; | ||
abstract visit<TNode extends Node, TParent extends Node>(node: TNode, parent: TParent | null, parentKey: VisitorKeys[TParent['type']] | null, listIdx?: number | null): void; | ||
abstract visit<TNode extends Node, TParent extends Node>(node: TNode, parent: TParent | null, parentKey: VisitorKeys[TParent['type']] | null, listIdx?: number | null): VisitorAction; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
338809
2640
+ Addedcaniuse-lite@1.0.30001636(transitive)
+ Addedelectron-to-chromium@1.4.807(transitive)
- Removedcaniuse-lite@1.0.30001632(transitive)
- Removedelectron-to-chromium@1.4.799(transitive)