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.
		
		
		
		
		
			
		
			
				
					355 lines
				
				12 KiB
			
		
		
			
		
	
	
					355 lines
				
				12 KiB
			| 
											3 years ago
										 | "use strict"; | ||
|  | 
 | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |   value: true | ||
|  | }); | ||
|  | exports.default = normalizeModuleAndLoadMetadata; | ||
|  | exports.hasExports = hasExports; | ||
|  | exports.isSideEffectImport = isSideEffectImport; | ||
|  | exports.validateImportInteropOption = validateImportInteropOption; | ||
|  | var _path = require("path"); | ||
|  | var _helperValidatorIdentifier = require("@babel/helper-validator-identifier"); | ||
|  | var _helperSplitExportDeclaration = require("@babel/helper-split-export-declaration"); | ||
|  | function hasExports(metadata) { | ||
|  |   return metadata.hasExports; | ||
|  | } | ||
|  | 
 | ||
|  | function isSideEffectImport(source) { | ||
|  |   return source.imports.size === 0 && source.importsNamespace.size === 0 && source.reexports.size === 0 && source.reexportNamespace.size === 0 && !source.reexportAll; | ||
|  | } | ||
|  | function validateImportInteropOption(importInterop) { | ||
|  |   if (typeof importInterop !== "function" && importInterop !== "none" && importInterop !== "babel" && importInterop !== "node") { | ||
|  |     throw new Error(`.importInterop must be one of "none", "babel", "node", or a function returning one of those values (received ${importInterop}).`); | ||
|  |   } | ||
|  |   return importInterop; | ||
|  | } | ||
|  | function resolveImportInterop(importInterop, source, filename) { | ||
|  |   if (typeof importInterop === "function") { | ||
|  |     return validateImportInteropOption(importInterop(source, filename)); | ||
|  |   } | ||
|  |   return importInterop; | ||
|  | } | ||
|  | 
 | ||
|  | function normalizeModuleAndLoadMetadata(programPath, exportName, { | ||
|  |   importInterop, | ||
|  |   initializeReexports = false, | ||
|  |   lazy = false, | ||
|  |   esNamespaceOnly = false, | ||
|  |   filename | ||
|  | }) { | ||
|  |   if (!exportName) { | ||
|  |     exportName = programPath.scope.generateUidIdentifier("exports").name; | ||
|  |   } | ||
|  |   const stringSpecifiers = new Set(); | ||
|  |   nameAnonymousExports(programPath); | ||
|  |   const { | ||
|  |     local, | ||
|  |     source, | ||
|  |     hasExports | ||
|  |   } = getModuleMetadata(programPath, { | ||
|  |     initializeReexports, | ||
|  |     lazy | ||
|  |   }, stringSpecifiers); | ||
|  |   removeImportExportDeclarations(programPath); | ||
|  | 
 | ||
|  |   for (const [, metadata] of source) { | ||
|  |     if (metadata.importsNamespace.size > 0) { | ||
|  |       metadata.name = metadata.importsNamespace.values().next().value; | ||
|  |     } | ||
|  |     const resolvedInterop = resolveImportInterop(importInterop, metadata.source, filename); | ||
|  |     if (resolvedInterop === "none") { | ||
|  |       metadata.interop = "none"; | ||
|  |     } else if (resolvedInterop === "node" && metadata.interop === "namespace") { | ||
|  |       metadata.interop = "node-namespace"; | ||
|  |     } else if (resolvedInterop === "node" && metadata.interop === "default") { | ||
|  |       metadata.interop = "node-default"; | ||
|  |     } else if (esNamespaceOnly && metadata.interop === "namespace") { | ||
|  |       metadata.interop = "default"; | ||
|  |     } | ||
|  |   } | ||
|  |   return { | ||
|  |     exportName, | ||
|  |     exportNameListName: null, | ||
|  |     hasExports, | ||
|  |     local, | ||
|  |     source, | ||
|  |     stringSpecifiers | ||
|  |   }; | ||
|  | } | ||
|  | function getExportSpecifierName(path, stringSpecifiers) { | ||
|  |   if (path.isIdentifier()) { | ||
|  |     return path.node.name; | ||
|  |   } else if (path.isStringLiteral()) { | ||
|  |     const stringValue = path.node.value; | ||
|  |     if (!(0, _helperValidatorIdentifier.isIdentifierName)(stringValue)) { | ||
|  |       stringSpecifiers.add(stringValue); | ||
|  |     } | ||
|  |     return stringValue; | ||
|  |   } else { | ||
|  |     throw new Error(`Expected export specifier to be either Identifier or StringLiteral, got ${path.node.type}`); | ||
|  |   } | ||
|  | } | ||
|  | function assertExportSpecifier(path) { | ||
|  |   if (path.isExportSpecifier()) { | ||
|  |     return; | ||
|  |   } else if (path.isExportNamespaceSpecifier()) { | ||
|  |     throw path.buildCodeFrameError("Export namespace should be first transformed by `@babel/plugin-proposal-export-namespace-from`."); | ||
|  |   } else { | ||
|  |     throw path.buildCodeFrameError("Unexpected export specifier type"); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function getModuleMetadata(programPath, { | ||
|  |   lazy, | ||
|  |   initializeReexports | ||
|  | }, stringSpecifiers) { | ||
|  |   const localData = getLocalExportMetadata(programPath, initializeReexports, stringSpecifiers); | ||
|  |   const sourceData = new Map(); | ||
|  |   const getData = sourceNode => { | ||
|  |     const source = sourceNode.value; | ||
|  |     let data = sourceData.get(source); | ||
|  |     if (!data) { | ||
|  |       data = { | ||
|  |         name: programPath.scope.generateUidIdentifier((0, _path.basename)(source, (0, _path.extname)(source))).name, | ||
|  |         interop: "none", | ||
|  |         loc: null, | ||
|  |         imports: new Map(), | ||
|  |         importsNamespace: new Set(), | ||
|  |         reexports: new Map(), | ||
|  |         reexportNamespace: new Set(), | ||
|  |         reexportAll: null, | ||
|  |         lazy: false, | ||
|  |         source | ||
|  |       }; | ||
|  |       sourceData.set(source, data); | ||
|  |     } | ||
|  |     return data; | ||
|  |   }; | ||
|  |   let hasExports = false; | ||
|  |   programPath.get("body").forEach(child => { | ||
|  |     if (child.isImportDeclaration()) { | ||
|  |       const data = getData(child.node.source); | ||
|  |       if (!data.loc) data.loc = child.node.loc; | ||
|  |       child.get("specifiers").forEach(spec => { | ||
|  |         if (spec.isImportDefaultSpecifier()) { | ||
|  |           const localName = spec.get("local").node.name; | ||
|  |           data.imports.set(localName, "default"); | ||
|  |           const reexport = localData.get(localName); | ||
|  |           if (reexport) { | ||
|  |             localData.delete(localName); | ||
|  |             reexport.names.forEach(name => { | ||
|  |               data.reexports.set(name, "default"); | ||
|  |             }); | ||
|  |           } | ||
|  |         } else if (spec.isImportNamespaceSpecifier()) { | ||
|  |           const localName = spec.get("local").node.name; | ||
|  |           data.importsNamespace.add(localName); | ||
|  |           const reexport = localData.get(localName); | ||
|  |           if (reexport) { | ||
|  |             localData.delete(localName); | ||
|  |             reexport.names.forEach(name => { | ||
|  |               data.reexportNamespace.add(name); | ||
|  |             }); | ||
|  |           } | ||
|  |         } else if (spec.isImportSpecifier()) { | ||
|  |           const importName = getExportSpecifierName(spec.get("imported"), stringSpecifiers); | ||
|  |           const localName = spec.get("local").node.name; | ||
|  |           data.imports.set(localName, importName); | ||
|  |           const reexport = localData.get(localName); | ||
|  |           if (reexport) { | ||
|  |             localData.delete(localName); | ||
|  |             reexport.names.forEach(name => { | ||
|  |               data.reexports.set(name, importName); | ||
|  |             }); | ||
|  |           } | ||
|  |         } | ||
|  |       }); | ||
|  |     } else if (child.isExportAllDeclaration()) { | ||
|  |       hasExports = true; | ||
|  |       const data = getData(child.node.source); | ||
|  |       if (!data.loc) data.loc = child.node.loc; | ||
|  |       data.reexportAll = { | ||
|  |         loc: child.node.loc | ||
|  |       }; | ||
|  |     } else if (child.isExportNamedDeclaration() && child.node.source) { | ||
|  |       hasExports = true; | ||
|  |       const data = getData(child.node.source); | ||
|  |       if (!data.loc) data.loc = child.node.loc; | ||
|  |       child.get("specifiers").forEach(spec => { | ||
|  |         assertExportSpecifier(spec); | ||
|  |         const importName = getExportSpecifierName(spec.get("local"), stringSpecifiers); | ||
|  |         const exportName = getExportSpecifierName(spec.get("exported"), stringSpecifiers); | ||
|  |         data.reexports.set(exportName, importName); | ||
|  |         if (exportName === "__esModule") { | ||
|  |           throw spec.get("exported").buildCodeFrameError('Illegal export "__esModule".'); | ||
|  |         } | ||
|  |       }); | ||
|  |     } else if (child.isExportNamedDeclaration() || child.isExportDefaultDeclaration()) { | ||
|  |       hasExports = true; | ||
|  |     } | ||
|  |   }); | ||
|  |   for (const metadata of sourceData.values()) { | ||
|  |     let needsDefault = false; | ||
|  |     let needsNamed = false; | ||
|  |     if (metadata.importsNamespace.size > 0) { | ||
|  |       needsDefault = true; | ||
|  |       needsNamed = true; | ||
|  |     } | ||
|  |     if (metadata.reexportAll) { | ||
|  |       needsNamed = true; | ||
|  |     } | ||
|  |     for (const importName of metadata.imports.values()) { | ||
|  |       if (importName === "default") needsDefault = true;else needsNamed = true; | ||
|  |     } | ||
|  |     for (const importName of metadata.reexports.values()) { | ||
|  |       if (importName === "default") needsDefault = true;else needsNamed = true; | ||
|  |     } | ||
|  |     if (needsDefault && needsNamed) { | ||
|  |       metadata.interop = "namespace"; | ||
|  |     } else if (needsDefault) { | ||
|  |       metadata.interop = "default"; | ||
|  |     } | ||
|  |   } | ||
|  |   for (const [source, metadata] of sourceData) { | ||
|  |     if (lazy !== false && !(isSideEffectImport(metadata) || metadata.reexportAll)) { | ||
|  |       if (lazy === true) { | ||
|  |         metadata.lazy = !/\./.test(source); | ||
|  |       } else if (Array.isArray(lazy)) { | ||
|  |         metadata.lazy = lazy.indexOf(source) !== -1; | ||
|  |       } else if (typeof lazy === "function") { | ||
|  |         metadata.lazy = lazy(source); | ||
|  |       } else { | ||
|  |         throw new Error(`.lazy must be a boolean, string array, or function`); | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  |   return { | ||
|  |     hasExports, | ||
|  |     local: localData, | ||
|  |     source: sourceData | ||
|  |   }; | ||
|  | } | ||
|  | function getLocalExportMetadata(programPath, initializeReexports, stringSpecifiers) { | ||
|  |   const bindingKindLookup = new Map(); | ||
|  |   programPath.get("body").forEach(child => { | ||
|  |     let kind; | ||
|  |     if (child.isImportDeclaration()) { | ||
|  |       kind = "import"; | ||
|  |     } else { | ||
|  |       if (child.isExportDefaultDeclaration()) { | ||
|  |         child = child.get("declaration"); | ||
|  |       } | ||
|  |       if (child.isExportNamedDeclaration()) { | ||
|  |         if (child.node.declaration) { | ||
|  |           child = child.get("declaration"); | ||
|  |         } else if (initializeReexports && child.node.source && child.get("source").isStringLiteral()) { | ||
|  |           child.get("specifiers").forEach(spec => { | ||
|  |             assertExportSpecifier(spec); | ||
|  |             bindingKindLookup.set(spec.get("local").node.name, "block"); | ||
|  |           }); | ||
|  |           return; | ||
|  |         } | ||
|  |       } | ||
|  |       if (child.isFunctionDeclaration()) { | ||
|  |         kind = "hoisted"; | ||
|  |       } else if (child.isClassDeclaration()) { | ||
|  |         kind = "block"; | ||
|  |       } else if (child.isVariableDeclaration({ | ||
|  |         kind: "var" | ||
|  |       })) { | ||
|  |         kind = "var"; | ||
|  |       } else if (child.isVariableDeclaration()) { | ||
|  |         kind = "block"; | ||
|  |       } else { | ||
|  |         return; | ||
|  |       } | ||
|  |     } | ||
|  |     Object.keys(child.getOuterBindingIdentifiers()).forEach(name => { | ||
|  |       bindingKindLookup.set(name, kind); | ||
|  |     }); | ||
|  |   }); | ||
|  |   const localMetadata = new Map(); | ||
|  |   const getLocalMetadata = idPath => { | ||
|  |     const localName = idPath.node.name; | ||
|  |     let metadata = localMetadata.get(localName); | ||
|  |     if (!metadata) { | ||
|  |       const kind = bindingKindLookup.get(localName); | ||
|  |       if (kind === undefined) { | ||
|  |         throw idPath.buildCodeFrameError(`Exporting local "${localName}", which is not declared.`); | ||
|  |       } | ||
|  |       metadata = { | ||
|  |         names: [], | ||
|  |         kind | ||
|  |       }; | ||
|  |       localMetadata.set(localName, metadata); | ||
|  |     } | ||
|  |     return metadata; | ||
|  |   }; | ||
|  |   programPath.get("body").forEach(child => { | ||
|  |     if (child.isExportNamedDeclaration() && (initializeReexports || !child.node.source)) { | ||
|  |       if (child.node.declaration) { | ||
|  |         const declaration = child.get("declaration"); | ||
|  |         const ids = declaration.getOuterBindingIdentifierPaths(); | ||
|  |         Object.keys(ids).forEach(name => { | ||
|  |           if (name === "__esModule") { | ||
|  |             throw declaration.buildCodeFrameError('Illegal export "__esModule".'); | ||
|  |           } | ||
|  |           getLocalMetadata(ids[name]).names.push(name); | ||
|  |         }); | ||
|  |       } else { | ||
|  |         child.get("specifiers").forEach(spec => { | ||
|  |           const local = spec.get("local"); | ||
|  |           const exported = spec.get("exported"); | ||
|  |           const localMetadata = getLocalMetadata(local); | ||
|  |           const exportName = getExportSpecifierName(exported, stringSpecifiers); | ||
|  |           if (exportName === "__esModule") { | ||
|  |             throw exported.buildCodeFrameError('Illegal export "__esModule".'); | ||
|  |           } | ||
|  |           localMetadata.names.push(exportName); | ||
|  |         }); | ||
|  |       } | ||
|  |     } else if (child.isExportDefaultDeclaration()) { | ||
|  |       const declaration = child.get("declaration"); | ||
|  |       if (declaration.isFunctionDeclaration() || declaration.isClassDeclaration()) { | ||
|  |         getLocalMetadata(declaration.get("id")).names.push("default"); | ||
|  |       } else { | ||
|  |         throw declaration.buildCodeFrameError("Unexpected default expression export."); | ||
|  |       } | ||
|  |     } | ||
|  |   }); | ||
|  |   return localMetadata; | ||
|  | } | ||
|  | 
 | ||
|  | function nameAnonymousExports(programPath) { | ||
|  |   programPath.get("body").forEach(child => { | ||
|  |     if (!child.isExportDefaultDeclaration()) return; | ||
|  |     (0, _helperSplitExportDeclaration.default)(child); | ||
|  |   }); | ||
|  | } | ||
|  | function removeImportExportDeclarations(programPath) { | ||
|  |   programPath.get("body").forEach(child => { | ||
|  |     if (child.isImportDeclaration()) { | ||
|  |       child.remove(); | ||
|  |     } else if (child.isExportNamedDeclaration()) { | ||
|  |       if (child.node.declaration) { | ||
|  |         child.node.declaration._blockHoist = child.node._blockHoist; | ||
|  |         child.replaceWith(child.node.declaration); | ||
|  |       } else { | ||
|  |         child.remove(); | ||
|  |       } | ||
|  |     } else if (child.isExportDefaultDeclaration()) { | ||
|  |       const declaration = child.get("declaration"); | ||
|  |       if (declaration.isFunctionDeclaration() || declaration.isClassDeclaration()) { | ||
|  |         declaration._blockHoist = child.node._blockHoist; | ||
|  |         child.replaceWith(declaration); | ||
|  |       } else { | ||
|  |         throw declaration.buildCodeFrameError("Unexpected default expression export."); | ||
|  |       } | ||
|  |     } else if (child.isExportAllDeclaration()) { | ||
|  |       child.remove(); | ||
|  |     } | ||
|  |   }); | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=normalize-and-load-metadata.js.map
 |