UNPKG

@linaria/utils

Version:

Blazing fast zero-runtime CSS in JS library

990 lines (969 loc) 31.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.collectExportsAndImports = collectExportsAndImports; exports.sideEffectImport = exports.explicitImport = void 0; var _logger = require("@linaria/logger"); var _getScope = require("./getScope"); var _isExports = _interopRequireDefault(require("./isExports")); var _isNotNull = _interopRequireDefault(require("./isNotNull")); var _isRequire = _interopRequireDefault(require("./isRequire")); var _isTypedNode = _interopRequireDefault(require("./isTypedNode")); var _traversalCache = require("./traversalCache"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint @typescript-eslint/no-use-before-define: ["error", { "functions": false }] */ /* eslint-disable no-restricted-syntax,no-continue */ // '*' means re-export all const sideEffectImport = item => item.imported === 'side-effect'; exports.sideEffectImport = sideEffectImport; const explicitImport = item => item.imported !== 'side-effect'; exports.explicitImport = explicitImport; function getValue({ node }) { return node.type === 'Identifier' ? node.name : node.value; } // We ignore imports and exports of types const isType = p => 'importKind' in p.node && p.node.importKind === 'type' || 'exportKind' in p.node && p.node.exportKind === 'type'; // Force TypeScript to check, that we have implementation for every possible specifier const collectors = { ImportSpecifier(path, source) { if (isType(path)) return []; const imported = getValue(path.get('imported')); const local = path.get('local'); return [{ imported, local, source, type: 'esm' }]; }, ImportDefaultSpecifier(path, source) { const local = path.get('local'); return [{ imported: 'default', local, source, type: 'esm' }]; }, ImportNamespaceSpecifier(path, source) { const local = path.get('local'); return unfoldNamespaceImport({ imported: '*', local, source, type: 'esm' }); } }; function collectFromImportDeclaration(path, state) { // If importKind is specified, and it's not a value, ignore that import if (isType(path)) return; const source = getValue(path.get('source')); const specifiers = path.get('specifiers'); if (specifiers.length === 0) { state.imports.push({ imported: 'side-effect', local: path, source }); } specifiers.forEach(specifier => { if (specifier.isImportSpecifier() && isType(specifier)) return; const collector = collectors[specifier.node.type]; state.imports.push(...collector(specifier, source)); }); } function getAncestorsWhile(path, cond) { const result = []; let current = path; while (current && cond(current)) { result.push(current); current = current.parentPath; } return result; } function whatIsDestructed(objectPattern) { const destructedProps = []; objectPattern.traverse({ Identifier(identifier) { if (identifier.isBindingIdentifier()) { const parent = identifier.parentPath; if (parent.isObjectProperty({ value: identifier.node })) { const chain = getAncestorsWhile(parent, p => p !== objectPattern).filter((0, _isTypedNode.default)('ObjectProperty')).map(p => { const key = p.get('key'); if (!key.isIdentifier()) { // TODO: try to process other type of keys or at least warn about this return null; } return key; }).filter(_isNotNull.default); chain.reverse(); if (chain.length > 0) { destructedProps.push({ what: chain[0].node.name, as: identifier }); } return; } if (parent.isRestElement({ argument: identifier.node })) { destructedProps.push({ what: '*', as: identifier }); } } } }); return destructedProps; } function importFromVariableDeclarator(path, isSync) { const id = path.get('id'); if (id.isIdentifier()) { // It's the simplest case when the full namespace is imported return [{ as: id, what: '*' }]; } if (!isSync) { // Something went wrong // Is it something like `const { … } = import(…)`? (0, _logger.debug)('evaluator:collectExportsAndImports', '`import` should be awaited'); return []; } if (id.isObjectPattern()) { return whatIsDestructed(id); } // What else it can be? (0, _logger.debug)('evaluator:collectExportsAndImports:importFromVariableDeclarator', 'Unknown type of id', id.node.type); return []; } const findIIFE = path => { if (path.isCallExpression() && path.get('callee').isFunctionExpression()) { return path; } if (!path.parentPath) { return null; } return findIIFE(path.parentPath); }; function exportFromVariableDeclarator(path) { const id = path.get('id'); const init = path.get('init'); // If there is no init and id is an identifier, we should find IIFE if (!init.node && id.isIdentifier()) { const binding = (0, _getScope.getScope)(path).getBinding(id.node.name); if (!binding) { return {}; } const iife = [...binding.referencePaths, ...binding.constantViolations, binding.path].map(findIIFE).find(_isNotNull.default); if (!iife) { return {}; } return { [id.node.name]: iife }; } if (!init || !init.isExpression()) { return {}; } if (id.isIdentifier()) { // It is `export const a = 1;` return { [id.node.name]: init }; } if (id.isObjectPattern()) { // It is `export const { a, ...rest } = obj;` return whatIsDestructed(id).reduce((acc, destructed) => ({ ...acc, [destructed.as.node.name]: init }), {}); } // What else it can be? (0, _logger.debug)('evaluator:collectExportsAndImports:exportFromVariableDeclarator', 'Unknown type of id', id.node.type); return {}; } function collectFromDynamicImport(path, state) { const { parentPath: callExpression } = path; if (!callExpression.isCallExpression()) { // It's wrong `import` return; } const [sourcePath] = callExpression.get('arguments'); if (!sourcePath || !sourcePath.isStringLiteral()) { // Import should have at least one argument, and it should be StringLiteral return; } const source = sourcePath.node.value; let { parentPath: container, key } = callExpression; let isAwaited = false; if (container.isAwaitExpression()) { // If it's not awaited import, it imports the full namespace isAwaited = true; key = container.key; container = container.parentPath; } // Is it `const something = await import("something")`? if (key === 'init' && container.isVariableDeclarator()) { importFromVariableDeclarator(container, isAwaited).map(prop => state.imports.push({ imported: prop.what, local: prop.as, source, type: 'dynamic' })); } } function getCalleeName(path) { const callee = path.get('callee'); if (callee.isIdentifier()) { return callee.node.name; } if (callee.isMemberExpression()) { const property = callee.get('property'); if (property.isIdentifier()) { return property.node.name; } } return undefined; } function getImportExportTypeByInteropFunction(path) { const name = getCalleeName(path); if (name === undefined) { return undefined; } if (name.startsWith('__exportStar')) { return 're-export:*'; } if (name.startsWith('_interopRequireDefault') || name.startsWith('__importDefault')) { return 'default'; } if (name.startsWith('_interopRequireWildcard') || name.startsWith('__importStar') || name.startsWith('__toESM')) { return 'import:*'; } if (name.startsWith('__rest') || name.startsWith('__objRest') || name.startsWith('_objectDestructuringEmpty')) { return 'import:*'; } return undefined; } function isAlreadyProcessed(path) { if (path.isCallExpression() && path.get('callee').isIdentifier({ name: '__toCommonJS' })) { // because its esbuild and we already processed all exports return true; } return false; } function collectFromRequire(path, state) { if (!(0, _isRequire.default)(path)) return; // This method can be reached many times from multiple visitors for the same path // So we need to check if we already processed it if (state.processedRequires.has(path)) return; state.processedRequires.add(path); const { parentPath: callExpression } = path; if (!callExpression.isCallExpression()) { // It's wrong `require` return; } const [sourcePath] = callExpression.get('arguments'); if (!sourcePath || !sourcePath.isStringLiteral()) { // Import should have at least one argument, and it should be StringLiteral return; } const source = sourcePath.node.value; const { parentPath: container, key } = callExpression; if (container.isCallExpression() && key === 0) { // It may be transpiled import such as // `var _atomic = _interopRequireDefault(require("@linaria/atomic"));` const imported = getImportExportTypeByInteropFunction(container); if (!imported) { // It's not a transpiled import. // TODO: Can we guess that it's a namespace import? (0, _logger.debug)('evaluator:collectExportsAndImports', 'Unknown wrapper of require', container.node.callee); return; } if (imported === 're-export:*') { state.reexports.push({ exported: '*', imported: '*', local: path, source }); return; } let { parentPath: variableDeclarator } = container; if (variableDeclarator.isCallExpression()) { if (variableDeclarator.get('callee').isIdentifier({ name: '_extends' })) { variableDeclarator = variableDeclarator.parentPath; } } if (!variableDeclarator.isVariableDeclarator()) { // TODO: Where else it can be? (0, _logger.debug)('evaluator:collectExportsAndImports', 'Unexpected require inside', variableDeclarator.node.type); return; } const id = variableDeclarator.get('id'); if (!id.isIdentifier()) { (0, _logger.debug)('evaluator:collectExportsAndImports', 'Id should be Identifier', variableDeclarator.node.type); return; } if (imported === 'import:*') { const unfolded = unfoldNamespaceImport({ imported: '*', local: id, source, type: 'cjs' }); state.imports.push(...unfolded); } else { state.imports.push({ imported, local: id, source, type: 'cjs' }); } } if (container.isMemberExpression()) { // It is `require('@linaria/shaker').dep` const property = container.get('property'); if (!property.isIdentifier() && !property.isStringLiteral()) { (0, _logger.debug)('evaluator:collectExportsAndImports', 'Property should be Identifier or StringLiteral', property.node.type); return; } const { parentPath: variableDeclarator } = container; if (variableDeclarator.isVariableDeclarator()) { // It is `const … = require('@linaria/shaker').dep`; const id = variableDeclarator.get('id'); if (id.isIdentifier()) { state.imports.push({ imported: getValue(property), local: id, source, type: 'cjs' }); } else { (0, _logger.debug)('evaluator:collectExportsAndImports', 'Id should be Identifier', variableDeclarator.node.type); } } else { // Maybe require is passed as an argument to some function? // Just use the whole MemberExpression as a local state.imports.push({ imported: getValue(property), local: container, source, type: 'cjs' }); } return; } // Is it `const something = require("something")`? if (key === 'init' && container.isVariableDeclarator()) { importFromVariableDeclarator(container, true).forEach(prop => { if (prop.what === '*') { const unfolded = unfoldNamespaceImport({ imported: '*', local: prop.as, source, type: 'cjs' }); state.imports.push(...unfolded); } else { state.imports.push({ imported: prop.what, local: prop.as, source, type: 'cjs' }); } }); } if (container.isExpressionStatement()) { // Looks like standalone require state.imports.push({ imported: 'side-effect', local: container, source }); } } function collectFromVariableDeclarator(path, state) { let found = false; path.traverse({ Identifier(identifierPath) { if ((0, _isRequire.default)(identifierPath)) { collectFromRequire(identifierPath, state); found = true; } } }); if (found) { path.skip(); } } function isChainOfVoidAssignment(path) { const right = path.get('right'); if (right.isUnaryExpression({ operator: 'void' })) { return true; } if (right.isAssignmentExpression()) { return isChainOfVoidAssignment(right); } return false; } function getReturnValue(path) { if (path.node.params.length !== 0) return undefined; const body = path.get('body'); if (body.isExpression()) { return body; } if (body.node.body.length === 1) { var _body$get; const returnStatement = (_body$get = body.get('body')) === null || _body$get === void 0 ? void 0 : _body$get[0]; if (!returnStatement.isReturnStatement()) return undefined; const argument = returnStatement.get('argument'); if (!argument.isExpression()) return undefined; return argument; } return undefined; } function getGetterValueFromDescriptor(descriptor) { const props = descriptor.get('properties').filter((0, _isTypedNode.default)('ObjectProperty')); const getter = props.find(p => p.get('key').isIdentifier({ name: 'get' })); const value = getter === null || getter === void 0 ? void 0 : getter.get('value'); if (value !== null && value !== void 0 && value.isFunctionExpression() || value !== null && value !== void 0 && value.isArrowFunctionExpression()) { return getReturnValue(value); } const valueProp = props.find(p => p.get('key').isIdentifier({ name: 'value' })); const valueValue = valueProp === null || valueProp === void 0 ? void 0 : valueProp.get('value'); return valueValue !== null && valueValue !== void 0 && valueValue.isExpression() ? valueValue : undefined; } function addExport(path, exported, state) { function getRelatedImport() { if (path.isMemberExpression()) { const object = path.get('object'); if (!object.isIdentifier()) { return undefined; } const objectBinding = object.scope.getBinding(object.node.name); if (!objectBinding) { return undefined; } if (objectBinding.path.isVariableDeclarator()) { collectFromVariableDeclarator(objectBinding.path, state); } const found = state.imports.find(i => objectBinding.identifier === i.local.node || objectBinding.referencePaths.some(p => i.local.isAncestor(p))); if (!found) { return undefined; } const property = path.get('property'); let what = '*'; if (path.node.computed && property.isStringLiteral()) { what = property.node.value; } else if (!path.node.computed && property.isIdentifier()) { what = property.node.name; } return { import: { ...found, local: path }, what }; } return undefined; } const relatedImport = getRelatedImport(); if (relatedImport) { // eslint-disable-next-line no-param-reassign state.reexports.push({ local: relatedImport.import.local, imported: relatedImport.import.imported, source: relatedImport.import.source, exported }); } else { // eslint-disable-next-line no-param-reassign state.exports[exported] = path; } } function collectFromExports(path, state) { if (!(0, _isExports.default)(path)) return; if (path.parentPath.isMemberExpression({ object: path.node })) { // It is `exports.prop = …` const memberExpression = path.parentPath; const property = memberExpression.get('property'); if (!property.isIdentifier() || memberExpression.node.computed) { return; } const exportName = property.node.name; const saveRef = () => { // Save all export.____ usages for later if (!state.exportRefs.has(exportName)) { state.exportRefs.set(exportName, []); } state.exportRefs.get(exportName).push(memberExpression); }; const assignmentExpression = memberExpression.parentPath; if (!assignmentExpression.isAssignmentExpression({ left: memberExpression.node })) { // If it's not `exports.prop = …`. Just save it. saveRef(); return; } const right = assignmentExpression.get('right'); if (isChainOfVoidAssignment(assignmentExpression)) { // It is `exports.foo = void 0` return; } const { name } = property.node; if (name === '__esModule') { // eslint-disable-next-line no-param-reassign state.isEsModule = true; return; } saveRef(); // eslint-disable-next-line no-param-reassign state.exports[property.node.name] = right; return; } if (path.parentPath.isCallExpression() && path.parentPath.get('callee').matchesPattern('Object.defineProperty')) { const [obj, prop, descriptor] = path.parentPath.get('arguments'); if (obj !== null && obj !== void 0 && obj.isIdentifier(path.node) && prop !== null && prop !== void 0 && prop.isStringLiteral() && descriptor !== null && descriptor !== void 0 && descriptor.isObjectExpression()) { if (prop.node.value === '__esModule') { // eslint-disable-next-line no-param-reassign state.isEsModule = true; } else { /** * Object.defineProperty(exports, "token", { * enumerable: true, * get: function get() { * return _unknownPackage.token; * } * }); */ const exported = prop.node.value; const local = getGetterValueFromDescriptor(descriptor); if (local) { addExport(local, exported, state); } } } else if (obj !== null && obj !== void 0 && obj.isIdentifier(path.node) && prop !== null && prop !== void 0 && prop.isIdentifier() && descriptor !== null && descriptor !== void 0 && descriptor.isObjectExpression()) { /** * Object.defineProperty(exports, key, { * enumerable: true, * get: function get() { * return _unknownPackage[key]; * } * }); */ const local = getGetterValueFromDescriptor(descriptor); if (local) { addExport(local, '*', state); } } } } function collectFromRequireOrExports(path, state) { if ((0, _isRequire.default)(path)) { collectFromRequire(path, state); } else if ((0, _isExports.default)(path)) { collectFromExports(path, state); } } function unfoldNamespaceImport(importItem) { const result = []; const { local } = importItem; if (!local.isIdentifier()) { // TODO: handle it return [importItem]; } const binding = (0, _getScope.getScope)(local).getBinding(local.node.name); if (!(binding !== null && binding !== void 0 && binding.referenced)) { // Imported namespace is not referenced and probably not used, // but it can have side effects, so we should keep it as is return [importItem]; } for (const referencePath of (_binding$referencePat = binding === null || binding === void 0 ? void 0 : binding.referencePaths) !== null && _binding$referencePat !== void 0 ? _binding$referencePat : []) { var _binding$referencePat; if (referencePath.find(ancestor => ancestor.isTSType() || ancestor.isFlowType())) { continue; } const { parentPath } = referencePath; if (parentPath !== null && parentPath !== void 0 && parentPath.isMemberExpression() && referencePath.key === 'object') { const property = parentPath.get('property'); const object = parentPath.get('object'); let imported; if (parentPath.node.computed && property.isStringLiteral()) { imported = property.node.value; } else if (!parentPath.node.computed && property.isIdentifier()) { imported = property.node.name; } else { imported = null; } if (object.isIdentifier() && imported) { result.push({ ...importItem, imported, local: parentPath }); } else { result.push(importItem); break; } continue; } if (parentPath !== null && parentPath !== void 0 && parentPath.isVariableDeclarator() && referencePath.key === 'init') { importFromVariableDeclarator(parentPath, true).map(prop => result.push({ ...importItem, imported: prop.what, local: prop.as })); continue; } if (parentPath !== null && parentPath !== void 0 && parentPath.isCallExpression() && referencePath.listKey === 'arguments') { // The defined variable is used as a function argument. Let's try to figure out what is imported. const importType = getImportExportTypeByInteropFunction(parentPath); if (!importType) { // Imported value is used as an unknown function argument, // so we can't predict usage and import it as is. result.push(importItem); break; } if (importType === 'default') { result.push({ ...importItem, imported: 'default', local: parentPath.get('id') }); continue; } if (importType === 'import:*') { result.push(importItem); break; } (0, _logger.debug)('evaluator:collectExportsAndImports:unfoldNamespaceImports', 'Unknown import type', importType); result.push(importItem); continue; } if (parentPath !== null && parentPath !== void 0 && parentPath.isExportSpecifier() || parentPath !== null && parentPath !== void 0 && parentPath.isExportDefaultDeclaration()) { // The whole namespace is re-exported result.push(importItem); break; } // Otherwise, we can't predict usage and import it as is // TODO: handle more cases (0, _logger.debug)('evaluator:collectExportsAndImports:unfoldNamespaceImports', 'Unknown reference', referencePath.node.type); result.push(importItem); break; } return result; } function collectFromExportAllDeclaration(path, state) { var _path$get; if (isType(path)) return; const source = (_path$get = path.get('source')) === null || _path$get === void 0 || (_path$get = _path$get.node) === null || _path$get === void 0 ? void 0 : _path$get.value; if (!source) return; // It is `export * from './css';` state.reexports.push({ exported: '*', imported: '*', local: path, source }); } function collectFromExportSpecifier(path, source, state) { if (path.isExportSpecifier()) { const exported = getValue(path.get('exported')); if (source) { // It is `export { foo } from './css';` const imported = path.get('local').node.name; state.reexports.push({ exported, imported, local: path, source }); } else { const local = path.get('local'); // eslint-disable-next-line no-param-reassign state.exports[exported] = local; } return; } if (path.isExportDefaultSpecifier() && source) { // It is `export default from './css';` state.reexports.push({ exported: 'default', imported: 'default', local: path, source }); } if (path.isExportNamespaceSpecifier() && source) { const exported = path.get('exported').node.name; // It is `export * as foo from './css';` state.reexports.push({ exported, imported: '*', local: path, source }); } // TODO: handle other cases (0, _logger.debug)('evaluator:collectExportsAndImports:collectFromExportSpecifier', 'Unprocessed ExportSpecifier', path.node.type); } function collectFromExportNamedDeclaration(path, state) { var _path$get2; if (isType(path)) return; const source = (_path$get2 = path.get('source')) === null || _path$get2 === void 0 || (_path$get2 = _path$get2.node) === null || _path$get2 === void 0 ? void 0 : _path$get2.value; const specifiers = path.get('specifiers'); if (specifiers) { specifiers.forEach(specifier => collectFromExportSpecifier(specifier, source, state)); } const declaration = path.get('declaration'); if (declaration.isVariableDeclaration()) { declaration.get('declarations').forEach(declarator => { // eslint-disable-next-line no-param-reassign state.exports = { ...state.exports, ...exportFromVariableDeclarator(declarator) }; }); } if (declaration.isTSEnumDeclaration()) { // eslint-disable-next-line no-param-reassign state.exports[declaration.get('id').node.name] = declaration; } if (declaration.isFunctionDeclaration()) { const id = declaration.get('id'); if (id.isIdentifier()) { // eslint-disable-next-line no-param-reassign state.exports[id.node.name] = id; } } if (declaration.isClassDeclaration()) { const id = declaration.get('id'); if (id.isIdentifier()) { // eslint-disable-next-line no-param-reassign state.exports[id.node.name] = id; } } } function collectFromExportDefaultDeclaration(path, state) { if (isType(path)) return; // eslint-disable-next-line no-param-reassign state.exports.default = path.get('declaration'); } function collectFromAssignmentExpression(path, state) { var _right$get; if (isChainOfVoidAssignment(path)) { return; } const left = path.get('left'); const right = path.get('right'); let exported; if (left.isMemberExpression() && (0, _isExports.default)(left.get('object'))) { const property = left.get('property'); if (property.isIdentifier()) { exported = property.node.name; } } else if ((0, _isExports.default)(left)) { // module.exports = ... if (!isAlreadyProcessed(right)) { exported = 'default'; } } if (!exported) return; if (!right.isCallExpression() || !(0, _isRequire.default)(right.get('callee'))) { // eslint-disable-next-line no-param-reassign state.exports[exported] = right; return; } const sourcePath = (_right$get = right.get('arguments')) === null || _right$get === void 0 ? void 0 : _right$get[0]; const source = sourcePath.isStringLiteral() ? sourcePath.node.value : undefined; if (!source) return; // It is `exports.foo = require('./css');` if (state.exports[exported]) { // eslint-disable-next-line no-param-reassign delete state.exports[exported]; } state.reexports.push({ exported, imported: '*', local: path, source }); path.skip(); } function collectFromExportStarCall(path, state) { var _requireCall$get; const [requireCall, exports] = path.get('arguments'); if (!(0, _isExports.default)(exports)) return; if (!requireCall.isCallExpression()) return; const callee = requireCall.get('callee'); const sourcePath = (_requireCall$get = requireCall.get('arguments')) === null || _requireCall$get === void 0 ? void 0 : _requireCall$get[0]; if (!(0, _isRequire.default)(callee) || !sourcePath.isStringLiteral()) return; const source = sourcePath.node.value; if (!source) return; state.reexports.push({ exported: '*', imported: '*', local: path, source }); path.skip(); } function collectFromMap(map, state) { const properties = map.get('properties'); properties.forEach(property => { if (!property.isObjectProperty()) return; const key = property.get('key'); const value = property.get('value'); if (!key.isIdentifier()) return; const exported = key.node.name; if (!value.isFunction()) return; if (value.node.params.length !== 0) return; const returnValue = getReturnValue(value); if (!returnValue) return; addExport(returnValue, exported, state); }); } function collectFromEsbuildExportCall(path, state) { const [sourceExports, map] = path.get('arguments'); if (!sourceExports.isIdentifier({ name: 'source_exports' })) return; if (!map.isObjectExpression()) return; collectFromMap(map, state); path.skip(); } function collectFromEsbuildReExportCall(path, state) { var _requireCall$get2; const [sourceExports, requireCall, exports] = path.get('arguments'); if (!sourceExports.isIdentifier({ name: 'source_exports' })) return; if (!requireCall.isCallExpression()) return; if (!(0, _isExports.default)(exports)) return; const callee = requireCall.get('callee'); if (!(0, _isRequire.default)(callee)) return; const sourcePath = (_requireCall$get2 = requireCall.get('arguments')) === null || _requireCall$get2 === void 0 ? void 0 : _requireCall$get2[0]; if (!sourcePath.isStringLiteral()) return; state.reexports.push({ exported: '*', imported: '*', local: path, source: sourcePath.node.value }); path.skip(); } function collectFromSwcExportCall(path, state) { const [exports, map] = path.get('arguments'); if (!(0, _isExports.default)(exports)) return; if (!map.isObjectExpression()) return; collectFromMap(map, state); path.skip(); } function collectFromCallExpression(path, state) { const maybeExportStart = path.get('callee'); if (!maybeExportStart.isIdentifier()) { return; } const { name } = maybeExportStart.node; // TypeScript if (name.startsWith('__exportStar')) { collectFromExportStarCall(path, state); return; } // swc if (name === '_exportStar') { collectFromExportStarCall(path, state); } if (name === '_export') { collectFromSwcExportCall(path, state); } // esbuild if (name === '__export') { collectFromEsbuildExportCall(path, state); } if (name === '__reExport') { collectFromEsbuildReExportCall(path, state); } } function collectExportsAndImports(path, cacheMode = 'enabled') { const localState = { deadExports: [], exportRefs: new Map(), exports: {}, imports: [], reexports: [], isEsModule: path.node.sourceType === 'module', processedRequires: new WeakSet() }; const cache = cacheMode !== 'disabled' ? (0, _traversalCache.getTraversalCache)(path, 'collectExportsAndImports') : undefined; if (cacheMode === 'enabled' && cache !== null && cache !== void 0 && cache.has(path)) { var _cache$get; return (_cache$get = cache.get(path)) !== null && _cache$get !== void 0 ? _cache$get : localState; } path.traverse({ AssignmentExpression: collectFromAssignmentExpression, CallExpression: collectFromCallExpression, ExportAllDeclaration: collectFromExportAllDeclaration, ExportDefaultDeclaration: collectFromExportDefaultDeclaration, ExportNamedDeclaration: collectFromExportNamedDeclaration, ImportDeclaration: collectFromImportDeclaration, Import: collectFromDynamicImport, Identifier: collectFromRequireOrExports, VariableDeclarator: collectFromVariableDeclarator }, localState); const { processedRequires, ...state } = localState; cache === null || cache === void 0 || cache.set(path, state); return state; } //# sourceMappingURL=collectExportsAndImports.js.map