You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					248 lines
				
				7.5 KiB
			
		
		
			
		
	
	
					248 lines
				
				7.5 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Object.defineProperty(exports, "__esModule", {
							 | 
						||
| 
								 | 
							
								  value: true
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								exports.default = void 0;
							 | 
						||
| 
								 | 
							
								exports.ensure = ensure;
							 | 
						||
| 
								 | 
							
								exports.get = get;
							 | 
						||
| 
								 | 
							
								exports.getDependencies = getDependencies;
							 | 
						||
| 
								 | 
							
								exports.list = void 0;
							 | 
						||
| 
								 | 
							
								exports.minVersion = minVersion;
							 | 
						||
| 
								 | 
							
								var _traverse = require("@babel/traverse");
							 | 
						||
| 
								 | 
							
								var _t = require("@babel/types");
							 | 
						||
| 
								 | 
							
								var _helpers = require("./helpers");
							 | 
						||
| 
								 | 
							
								const {
							 | 
						||
| 
								 | 
							
								  assignmentExpression,
							 | 
						||
| 
								 | 
							
								  cloneNode,
							 | 
						||
| 
								 | 
							
								  expressionStatement,
							 | 
						||
| 
								 | 
							
								  file,
							 | 
						||
| 
								 | 
							
								  identifier
							 | 
						||
| 
								 | 
							
								} = _t;
							 | 
						||
| 
								 | 
							
								function makePath(path) {
							 | 
						||
| 
								 | 
							
								  const parts = [];
							 | 
						||
| 
								 | 
							
								  for (; path.parentPath; path = path.parentPath) {
							 | 
						||
| 
								 | 
							
								    parts.push(path.key);
							 | 
						||
| 
								 | 
							
								    if (path.inList) parts.push(path.listKey);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return parts.reverse().join(".");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								let FileClass = undefined;
							 | 
						||
| 
								 | 
							
								function getHelperMetadata(file) {
							 | 
						||
| 
								 | 
							
								  const globals = new Set();
							 | 
						||
| 
								 | 
							
								  const localBindingNames = new Set();
							 | 
						||
| 
								 | 
							
								  const dependencies = new Map();
							 | 
						||
| 
								 | 
							
								  let exportName;
							 | 
						||
| 
								 | 
							
								  let exportPath;
							 | 
						||
| 
								 | 
							
								  const exportBindingAssignments = [];
							 | 
						||
| 
								 | 
							
								  const importPaths = [];
							 | 
						||
| 
								 | 
							
								  const importBindingsReferences = [];
							 | 
						||
| 
								 | 
							
								  const dependencyVisitor = {
							 | 
						||
| 
								 | 
							
								    ImportDeclaration(child) {
							 | 
						||
| 
								 | 
							
								      const name = child.node.source.value;
							 | 
						||
| 
								 | 
							
								      if (!_helpers.default[name]) {
							 | 
						||
| 
								 | 
							
								        throw child.buildCodeFrameError(`Unknown helper ${name}`);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (child.get("specifiers").length !== 1 ||
							 | 
						||
| 
								 | 
							
								      !child.get("specifiers.0").isImportDefaultSpecifier()) {
							 | 
						||
| 
								 | 
							
								        throw child.buildCodeFrameError("Helpers can only import a default value");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      const bindingIdentifier = child.node.specifiers[0].local;
							 | 
						||
| 
								 | 
							
								      dependencies.set(bindingIdentifier, name);
							 | 
						||
| 
								 | 
							
								      importPaths.push(makePath(child));
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    ExportDefaultDeclaration(child) {
							 | 
						||
| 
								 | 
							
								      const decl = child.get("declaration");
							 | 
						||
| 
								 | 
							
								      if (!decl.isFunctionDeclaration() || !decl.node.id) {
							 | 
						||
| 
								 | 
							
								        throw decl.buildCodeFrameError("Helpers can only export named function declarations");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      exportName = decl.node.id.name;
							 | 
						||
| 
								 | 
							
								      exportPath = makePath(child);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    ExportAllDeclaration(child) {
							 | 
						||
| 
								 | 
							
								      throw child.buildCodeFrameError("Helpers can only export default");
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    ExportNamedDeclaration(child) {
							 | 
						||
| 
								 | 
							
								      throw child.buildCodeFrameError("Helpers can only export default");
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    Statement(child) {
							 | 
						||
| 
								 | 
							
								      if (child.isImportDeclaration() || child.isExportDeclaration()) return;
							 | 
						||
| 
								 | 
							
								      child.skip();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  const referenceVisitor = {
							 | 
						||
| 
								 | 
							
								    Program(path) {
							 | 
						||
| 
								 | 
							
								      const bindings = path.scope.getAllBindings();
							 | 
						||
| 
								 | 
							
								      Object.keys(bindings).forEach(name => {
							 | 
						||
| 
								 | 
							
								        if (name === exportName) return;
							 | 
						||
| 
								 | 
							
								        if (dependencies.has(bindings[name].identifier)) return;
							 | 
						||
| 
								 | 
							
								        localBindingNames.add(name);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    ReferencedIdentifier(child) {
							 | 
						||
| 
								 | 
							
								      const name = child.node.name;
							 | 
						||
| 
								 | 
							
								      const binding = child.scope.getBinding(name);
							 | 
						||
| 
								 | 
							
								      if (!binding) {
							 | 
						||
| 
								 | 
							
								        globals.add(name);
							 | 
						||
| 
								 | 
							
								      } else if (dependencies.has(binding.identifier)) {
							 | 
						||
| 
								 | 
							
								        importBindingsReferences.push(makePath(child));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    AssignmentExpression(child) {
							 | 
						||
| 
								 | 
							
								      const left = child.get("left");
							 | 
						||
| 
								 | 
							
								      if (!(exportName in left.getBindingIdentifiers())) return;
							 | 
						||
| 
								 | 
							
								      if (!left.isIdentifier()) {
							 | 
						||
| 
								 | 
							
								        throw left.buildCodeFrameError("Only simple assignments to exports are allowed in helpers");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      const binding = child.scope.getBinding(exportName);
							 | 
						||
| 
								 | 
							
								      if (binding != null && binding.scope.path.isProgram()) {
							 | 
						||
| 
								 | 
							
								        exportBindingAssignments.push(makePath(child));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  (0, _traverse.default)(file.ast, dependencyVisitor, file.scope);
							 | 
						||
| 
								 | 
							
								  (0, _traverse.default)(file.ast, referenceVisitor, file.scope);
							 | 
						||
| 
								 | 
							
								  if (!exportPath) throw new Error("Helpers must have a default export.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  exportBindingAssignments.reverse();
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    globals: Array.from(globals),
							 | 
						||
| 
								 | 
							
								    localBindingNames: Array.from(localBindingNames),
							 | 
						||
| 
								 | 
							
								    dependencies,
							 | 
						||
| 
								 | 
							
								    exportBindingAssignments,
							 | 
						||
| 
								 | 
							
								    exportPath,
							 | 
						||
| 
								 | 
							
								    exportName,
							 | 
						||
| 
								 | 
							
								    importBindingsReferences,
							 | 
						||
| 
								 | 
							
								    importPaths
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
							 | 
						||
| 
								 | 
							
								  if (localBindings && !id) {
							 | 
						||
| 
								 | 
							
								    throw new Error("Unexpected local bindings for module-based helpers.");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (!id) return;
							 | 
						||
| 
								 | 
							
								  const {
							 | 
						||
| 
								 | 
							
								    localBindingNames,
							 | 
						||
| 
								 | 
							
								    dependencies,
							 | 
						||
| 
								 | 
							
								    exportBindingAssignments,
							 | 
						||
| 
								 | 
							
								    exportPath,
							 | 
						||
| 
								 | 
							
								    exportName,
							 | 
						||
| 
								 | 
							
								    importBindingsReferences,
							 | 
						||
| 
								 | 
							
								    importPaths
							 | 
						||
| 
								 | 
							
								  } = metadata;
							 | 
						||
| 
								 | 
							
								  const dependenciesRefs = {};
							 | 
						||
| 
								 | 
							
								  dependencies.forEach((name, id) => {
							 | 
						||
| 
								 | 
							
								    dependenciesRefs[id.name] = typeof getDependency === "function" && getDependency(name) || id;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  const toRename = {};
							 | 
						||
| 
								 | 
							
								  const bindings = new Set(localBindings || []);
							 | 
						||
| 
								 | 
							
								  localBindingNames.forEach(name => {
							 | 
						||
| 
								 | 
							
								    let newName = name;
							 | 
						||
| 
								 | 
							
								    while (bindings.has(newName)) newName = "_" + newName;
							 | 
						||
| 
								 | 
							
								    if (newName !== name) toRename[name] = newName;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  if (id.type === "Identifier" && exportName !== id.name) {
							 | 
						||
| 
								 | 
							
								    toRename[exportName] = id.name;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const {
							 | 
						||
| 
								 | 
							
								    path
							 | 
						||
| 
								 | 
							
								  } = file;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const exp = path.get(exportPath);
							 | 
						||
| 
								 | 
							
								  const imps = importPaths.map(p => path.get(p));
							 | 
						||
| 
								 | 
							
								  const impsBindingRefs = importBindingsReferences.map(p => path.get(p));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const decl = exp.get("declaration");
							 | 
						||
| 
								 | 
							
								  if (id.type === "Identifier") {
							 | 
						||
| 
								 | 
							
								    exp.replaceWith(decl);
							 | 
						||
| 
								 | 
							
								  } else if (id.type === "MemberExpression") {
							 | 
						||
| 
								 | 
							
								    exportBindingAssignments.forEach(assignPath => {
							 | 
						||
| 
								 | 
							
								      const assign = path.get(assignPath);
							 | 
						||
| 
								 | 
							
								      assign.replaceWith(assignmentExpression("=", id, assign.node));
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    exp.replaceWith(decl);
							 | 
						||
| 
								 | 
							
								    path.pushContainer("body", expressionStatement(assignmentExpression("=", id, identifier(exportName))));
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    throw new Error("Unexpected helper format.");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  Object.keys(toRename).forEach(name => {
							 | 
						||
| 
								 | 
							
								    path.scope.rename(name, toRename[name]);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  for (const path of imps) path.remove();
							 | 
						||
| 
								 | 
							
								  for (const path of impsBindingRefs) {
							 | 
						||
| 
								 | 
							
								    const node = cloneNode(dependenciesRefs[path.node.name]);
							 | 
						||
| 
								 | 
							
								    path.replaceWith(node);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								const helperData = Object.create(null);
							 | 
						||
| 
								 | 
							
								function loadHelper(name) {
							 | 
						||
| 
								 | 
							
								  if (!helperData[name]) {
							 | 
						||
| 
								 | 
							
								    const helper = _helpers.default[name];
							 | 
						||
| 
								 | 
							
								    if (!helper) {
							 | 
						||
| 
								 | 
							
								      throw Object.assign(new ReferenceError(`Unknown helper ${name}`), {
							 | 
						||
| 
								 | 
							
								        code: "BABEL_HELPER_UNKNOWN",
							 | 
						||
| 
								 | 
							
								        helper: name
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    const fn = () => {
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        if (!FileClass) {
							 | 
						||
| 
								 | 
							
								          const fakeFile = {
							 | 
						||
| 
								 | 
							
								            ast: file(helper.ast()),
							 | 
						||
| 
								 | 
							
								            path: null
							 | 
						||
| 
								 | 
							
								          };
							 | 
						||
| 
								 | 
							
								          (0, _traverse.default)(fakeFile.ast, {
							 | 
						||
| 
								 | 
							
								            Program: path => (fakeFile.path = path).stop()
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          return fakeFile;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return new FileClass({
							 | 
						||
| 
								 | 
							
								        filename: `babel-helper://${name}`
							 | 
						||
| 
								 | 
							
								      }, {
							 | 
						||
| 
								 | 
							
								        ast: file(helper.ast()),
							 | 
						||
| 
								 | 
							
								        code: "[internal Babel helper code]",
							 | 
						||
| 
								 | 
							
								        inputMap: null
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let metadata = null;
							 | 
						||
| 
								 | 
							
								    helperData[name] = {
							 | 
						||
| 
								 | 
							
								      minVersion: helper.minVersion,
							 | 
						||
| 
								 | 
							
								      build(getDependency, id, localBindings) {
							 | 
						||
| 
								 | 
							
								        const file = fn();
							 | 
						||
| 
								 | 
							
								        metadata || (metadata = getHelperMetadata(file));
							 | 
						||
| 
								 | 
							
								        permuteHelperAST(file, metadata, id, localBindings, getDependency);
							 | 
						||
| 
								 | 
							
								        return {
							 | 
						||
| 
								 | 
							
								          nodes: file.ast.program.body,
							 | 
						||
| 
								 | 
							
								          globals: metadata.globals
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      getDependencies() {
							 | 
						||
| 
								 | 
							
								        metadata || (metadata = getHelperMetadata(fn()));
							 | 
						||
| 
								 | 
							
								        return Array.from(metadata.dependencies.values());
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return helperData[name];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								function get(name, getDependency, id, localBindings) {
							 | 
						||
| 
								 | 
							
								  return loadHelper(name).build(getDependency, id, localBindings);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								function minVersion(name) {
							 | 
						||
| 
								 | 
							
								  return loadHelper(name).minVersion;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								function getDependencies(name) {
							 | 
						||
| 
								 | 
							
								  return loadHelper(name).getDependencies();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								function ensure(name, newFileClass) {
							 | 
						||
| 
								 | 
							
								  FileClass || (FileClass = newFileClass);
							 | 
						||
| 
								 | 
							
								  loadHelper(name);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								const list = Object.keys(_helpers.default).map(name => name.replace(/^_/, ""));
							 | 
						||
| 
								 | 
							
								exports.list = list;
							 | 
						||
| 
								 | 
							
								var _default = get;
							 | 
						||
| 
								 | 
							
								exports.default = _default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//# sourceMappingURL=index.js.map
							 |