| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const { SyncBailHook } = require("tapable");const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");const ConstDependency = require("./ConstDependency");module.exports = class HarmonyImportDependencyParserPlugin {	constructor(moduleOptions) {		this.strictExportPresence = moduleOptions.strictExportPresence;		this.strictThisContextOnImports = moduleOptions.strictThisContextOnImports;	}	apply(parser) {		parser.hooks.import.tap(			"HarmonyImportDependencyParserPlugin",			(statement, source) => {				parser.state.lastHarmonyImportOrder =					(parser.state.lastHarmonyImportOrder || 0) + 1;				const clearDep = new ConstDependency("", statement.range);				clearDep.loc = statement.loc;				parser.state.module.addDependency(clearDep);				const sideEffectDep = new HarmonyImportSideEffectDependency(					source,					parser.state.module,					parser.state.lastHarmonyImportOrder,					parser.state.harmonyParserScope				);				sideEffectDep.loc = statement.loc;				parser.state.module.addDependency(sideEffectDep);				return true;			}		);		parser.hooks.importSpecifier.tap(			"HarmonyImportDependencyParserPlugin",			(statement, source, id, name) => {				parser.scope.definitions.delete(name);				parser.scope.renames.set(name, "imported var");				if (!parser.state.harmonySpecifier) {					parser.state.harmonySpecifier = new Map();				}				parser.state.harmonySpecifier.set(name, {					source,					id,					sourceOrder: parser.state.lastHarmonyImportOrder				});				return true;			}		);		parser.hooks.expression			.for("imported var")			.tap("HarmonyImportDependencyParserPlugin", expr => {				const name = expr.name;				const settings = parser.state.harmonySpecifier.get(name);				const dep = new HarmonyImportSpecifierDependency(					settings.source,					parser.state.module,					settings.sourceOrder,					parser.state.harmonyParserScope,					settings.id,					name,					expr.range,					this.strictExportPresence				);				dep.shorthand = parser.scope.inShorthand;				dep.directImport = true;				dep.loc = expr.loc;				parser.state.module.addDependency(dep);				return true;			});		parser.hooks.expressionAnyMember			.for("imported var")			.tap("HarmonyImportDependencyParserPlugin", expr => {				const name = expr.object.name;				const settings = parser.state.harmonySpecifier.get(name);				if (settings.id !== null) return false;				const dep = new HarmonyImportSpecifierDependency(					settings.source,					parser.state.module,					settings.sourceOrder,					parser.state.harmonyParserScope,					expr.property.name || expr.property.value,					name,					expr.range,					this.strictExportPresence				);				dep.shorthand = parser.scope.inShorthand;				dep.directImport = false;				dep.loc = expr.loc;				parser.state.module.addDependency(dep);				return true;			});		if (this.strictThisContextOnImports) {			// only in case when we strictly follow the spec we need a special case here			parser.hooks.callAnyMember				.for("imported var")				.tap("HarmonyImportDependencyParserPlugin", expr => {					if (expr.callee.type !== "MemberExpression") return;					if (expr.callee.object.type !== "Identifier") return;					const name = expr.callee.object.name;					const settings = parser.state.harmonySpecifier.get(name);					if (settings.id !== null) return false;					const dep = new HarmonyImportSpecifierDependency(						settings.source,						parser.state.module,						settings.sourceOrder,						parser.state.harmonyParserScope,						expr.callee.property.name || expr.callee.property.value,						name,						expr.callee.range,						this.strictExportPresence					);					dep.shorthand = parser.scope.inShorthand;					dep.directImport = false;					dep.namespaceObjectAsContext = true;					dep.loc = expr.callee.loc;					parser.state.module.addDependency(dep);					if (expr.arguments) parser.walkExpressions(expr.arguments);					return true;				});		}		parser.hooks.call			.for("imported var")			.tap("HarmonyImportDependencyParserPlugin", expr => {				const args = expr.arguments;				const fullExpr = expr;				expr = expr.callee;				if (expr.type !== "Identifier") return;				const name = expr.name;				const settings = parser.state.harmonySpecifier.get(name);				const dep = new HarmonyImportSpecifierDependency(					settings.source,					parser.state.module,					settings.sourceOrder,					parser.state.harmonyParserScope,					settings.id,					name,					expr.range,					this.strictExportPresence				);				dep.directImport = true;				dep.callArgs = args;				dep.call = fullExpr;				dep.loc = expr.loc;				parser.state.module.addDependency(dep);				if (args) parser.walkExpressions(args);				return true;			});		// TODO webpack 5: refactor this, no custom hooks		if (!parser.hooks.hotAcceptCallback) {			parser.hooks.hotAcceptCallback = new SyncBailHook([				"expression",				"requests"			]);		}		if (!parser.hooks.hotAcceptWithoutCallback) {			parser.hooks.hotAcceptWithoutCallback = new SyncBailHook([				"expression",				"requests"			]);		}		parser.hooks.hotAcceptCallback.tap(			"HarmonyImportDependencyParserPlugin",			(expr, requests) => {				const harmonyParserScope = parser.state.harmonyParserScope;				if (!harmonyParserScope) {					// This is not a harmony module, skip it					return;				}				const dependencies = requests.map(request => {					const dep = new HarmonyAcceptImportDependency(						request,						parser.state.module,						harmonyParserScope					);					dep.loc = expr.loc;					parser.state.module.addDependency(dep);					return dep;				});				if (dependencies.length > 0) {					const dep = new HarmonyAcceptDependency(						expr.range,						dependencies,						true					);					dep.loc = expr.loc;					parser.state.module.addDependency(dep);				}			}		);		parser.hooks.hotAcceptWithoutCallback.tap(			"HarmonyImportDependencyParserPlugin",			(expr, requests) => {				const dependencies = requests.map(request => {					const dep = new HarmonyAcceptImportDependency(						request,						parser.state.module,						parser.state.harmonyParserScope					);					dep.loc = expr.loc;					parser.state.module.addDependency(dep);					return dep;				});				if (dependencies.length > 0) {					const dep = new HarmonyAcceptDependency(						expr.range,						dependencies,						false					);					dep.loc = expr.loc;					parser.state.module.addDependency(dep);				}			}		);	}};
 |