From 38acabfa6089ab8ac469c12b5f55022fb96935e5 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 23 Aug 2021 16:46:06 -0300 Subject: added web vendors --- @linaria/packages/shaker/src/Visitors.ts | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 @linaria/packages/shaker/src/Visitors.ts (limited to '@linaria/packages/shaker/src/Visitors.ts') diff --git a/@linaria/packages/shaker/src/Visitors.ts b/@linaria/packages/shaker/src/Visitors.ts new file mode 100644 index 0000000..0228d4a --- /dev/null +++ b/@linaria/packages/shaker/src/Visitors.ts @@ -0,0 +1,87 @@ +import { types as t } from '@babel/core'; +import type { Identifier, Node, VisitorKeys } from '@babel/types'; +import { warn } from '@linaria/logger'; +import { peek } from '@linaria/babel-preset'; +import GraphBuilderState from './GraphBuilderState'; +import identifierHandlers from './identifierHandlers'; +import type { Visitor, Visitors } from './types'; + +import { visitors as core } from './langs/core'; + +const visitors: Visitors = { + Identifier( + this: GraphBuilderState, + node: Identifier, + parent: TParent | null, + parentKey: VisitorKeys[TParent['type']] | null, + listIdx: number | null = null + ) { + if (!parent || !parentKey) { + return; + } + + const handler = identifierHandlers[`${parent.type}:${parentKey}`]; + + if (typeof handler === 'function') { + handler(this, node, parent, parentKey, listIdx); + return; + } + + if (handler === 'keep') { + return; + } + + if (handler === 'declare') { + const kindOfDeclaration = this.meta.get('kind-of-declaration'); + this.scope.declare(node, kindOfDeclaration === 'var', null); + return; + } + + if (handler === 'refer') { + const declaration = this.scope.addReference(node); + // Let's check that it's not a global variable + if (declaration) { + // usage of a variable depends on its declaration + this.graph.addEdge(node, declaration); + + const context = peek(this.context); + if (context === 'lval') { + // This is an identifier in the left side of an assignment expression and a variable value depends on that. + this.graph.addEdge(declaration, node); + } + } + + return; + } + + /* + * There is an unhandled identifier. + * This case should be added to ./identifierHandlers.ts + */ + warn( + 'evaluator:shaker', + 'Unhandled identifier', + node.name, + parent.type, + parentKey, + listIdx + ); + }, + + ...core, +}; + +const isKeyOfVisitors = (type: string): type is keyof Visitors => + type in visitors; + +export function getVisitors(node: TNode): Visitor[] { + const aliases = t.ALIAS_KEYS[node.type] || []; + const aliasVisitors = aliases + .map((type) => (isKeyOfVisitors(type) ? visitors[type] : null)) + .filter((i) => i) as Visitor[]; + return [...aliasVisitors, visitors[node.type] as Visitor].filter( + (v) => v + ); +} + +export default visitors; -- cgit v1.2.3