Socket
Socket
Sign inDemoInstall

@linaria/shaker

Package Overview
Dependencies
204
Maintainers
4
Versions
49
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0-beta.13 to 3.0.0-beta.14

12

CHANGELOG.md

@@ -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 @@

4

esm/graphBuilder.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc