UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

281 lines (254 loc) • 8.78 kB
/** * Matches assignment * foo.bar = 1 * @param node ast * @param part1 * @param part2 */ export function matchesAssignmentExpression(node: any, part1: string, part2: string): boolean { if (node.type === "ExpressionStatement") { if (node.expression && node.expression.type === "AssignmentExpression") { const expr = node.expression; if (expr.left && expr.left.type === "MemberExpression") { const left = expr.left; let part1Matched = false; let part2Matched = false; if (left.object && left.object.type === "Identifier") { if (left.object.name === part1) { part1Matched = true; } } if (left.property && left.property.type === "Identifier") { if (left.property.name === part2) { part2Matched = true; } } return part1Matched && part2Matched; } } } } export function matchesLiteralStringExpression(node: any, text: string) { return node.type === "ExpressionStatement" && node.expression.type === "Literal" && node.expression.value === text } const ES6_TYPES = new Set([ "ClassDeclaration", "SpreadElement", "ArrowFunctionExpression" ]); export function matchesIfStatementProcessEnv(node): string { if (node.type && node.type === "IfStatement") { // prevent detecting if else statement if (node.$parent && node.$parent.type === "IfStatement") { return; } if (node.test && node.test.type === "BinaryExpression") { if (node.test.left) { const variableName = matchesNodeEnv(node.test.left); return variableName; } } } } export function matchesIfStatementFuseBoxIsEnvironment(node) { if (node.type && node.type === "IfStatement") { if (node.test && node.test.type === "MemberExpression") { const test = node.test; if (test.object.type === "Identifier" && test.object.name === "FuseBox" && test.property) { return test.property.name; } } } } export function compareStatement(node: any, input: string | undefined) { const right = node.test.right; if (right) { const operator = node.test.operator; if (right.type === "Literal") { const value = right.value; if (operator === "===" || operator === "==") { //if ( "production" === "production" ) {} return value === input; } if (operator === "!==" || operator === "!=") { //if ( "production" !== "production" ) {} return value !== input; } } if (right.type === "Identifier" && right.name === "undefined") { if (operator === "!==" || operator === "!=") { return input !== undefined; } if (operator === "===" || operator === "==") { return input === undefined; } } } } export function matchesNodeEnv(node, veriableName?: string) { let isProcess, isEnv; isProcess = astQuery(node, ["/MemberExpression", ".object", "/MemberExpression", ".object", ".name"], 'process') if (!isProcess) { return false } isEnv = astQuery(node, ["/MemberExpression", ".object", "/MemberExpression", ".property", ".name"], "env"); if (!isEnv) { return false; } if (node.property) { let value; if (node.property.type === "Literal") { value = node.property.value; } if (node.property.type === "Identifier") { value = node.property.name; } return veriableName !== undefined ? veriableName === value : value; } } export function matchesEcmaScript6(node) { if (node) { if (ES6_TYPES.has(node.type)) { return true; } if (node.type === "VariableDeclaration" && node.kind !== "var") { return true; } } return false; } export function matchesSingleFunction(node: any, name: string) { return node.callee && node.callee.type === "Identifier" && node.callee.name === name } export function trackRequireMember(node: any, name: string): string { if (node && node.type === "MemberExpression") { if (node.object && node.object.type === "Identifier" && node.object.name === name) { if (node.property && node.property.type === "Identifier") { return node.property.name; } } } } export function matchRequireIdentifier(node: any): string { let name; if (node && node.type === "VariableDeclarator") { if (node.id && node.id.type === "Identifier") { name = node.id.name; if (node.init && node.init.type === "CallExpression") { if (matchesSingleFunction(node.init, "require")) { return name; } } } } } export function matchesTypeOf(node: any, name: string) { return node && node.operator === "typeof" && node.argument && node.argument.type === "Identifier" && node.argument.name === name; } export function isExportComputed(node: any, fn: { (result: boolean) }) { if (astQuery(node, [ "/MemberExpression", ".object", ".name" ], "exports")) { return fn(node.computed === true); } } export function isExportMisused(node: any, fn: { (name: string) }) { const isMisused = astQuery(node, [ "/MemberExpression", ".object", "/MemberExpression", ".object", ".name" ], "exports"); if (isMisused) { if (node.object.property && node.object.property.name) { return fn(node.object.property.name); } } } export function matchNamedExport(node: any, fn: any) { if (astQuery(node, ["/ExpressionStatement", ".expression", "/AssignmentExpression", ".left", "/MemberExpression", ".object", ".name"], "exports")) { if (node.expression.left.property.type === "Identifier") { let referencedVariable; if (node.expression.right) { const right = node.expression.right; if (right.object && right.object.type === "Identifier") { referencedVariable = right.object.name; } } fn(node.expression.left.property.name, referencedVariable); return true; } } } export function matchesDoubleMemberExpression(node: any, part1: string, part2?: string) { const matches = node.type === "MemberExpression" && node.object && node.object.type === "Identifier" && node.object && node.object.name === part1 && node.property if (!part2) { return matches; } return node.property && node.property.name === part2; } export function matchesExportReference(node: any): string { if (node.type === "MemberExpression" && node.object && node.object.type === "Identifier" && node.object && node.object.name === "exports" && node.property) { if (node.property.type === "Identifier") { return node.property.name; } } } export function matcheObjectDefineProperty(node, name: string) { if (astQuery(node, ["/ExpressionStatement", ".expression", "/CallExpression", ".callee", "/MemberExpression", ".object", ".name"], "Object")) { return astQuery(node, ["/ExpressionStatement", ".expression", "/CallExpression", ".arguments", 0, ".name"], name) } } export function astQuery(node, args: any[], value?: string) { let obj = node; for (const i in args) { if (obj === undefined) { return; } let spec = args[i]; let item; let lookForType = false; let lookForProp = false; if (typeof spec === "number") { item = spec; lookForProp = true; } else { item = spec.slice(1); if (spec.charAt(0) === "/") { lookForType = true; } if (spec.charAt(0) === ".") { lookForProp = true; } } if (lookForType) { if (!obj.type) { return; } if (obj.type !== item) { obj = undefined; } } if (lookForProp) { obj = obj[item]; } } if (value !== undefined) { return obj === value; } return obj; }