mirror of https://github.com/webpack/webpack.git
upgrade tapable from Parser
This commit is contained in:
parent
3f453a4f3c
commit
c10da6c285
|
|
@ -11,6 +11,7 @@ const ConstDependency = require("./dependencies/ConstDependency");
|
||||||
const NullFactory = require("./NullFactory");
|
const NullFactory = require("./NullFactory");
|
||||||
const ParserHelpers = require("./ParserHelpers");
|
const ParserHelpers = require("./ParserHelpers");
|
||||||
const createHash = require("./util/createHash");
|
const createHash = require("./util/createHash");
|
||||||
|
const SyncBailHook = require("tapable").SyncBailHook;
|
||||||
|
|
||||||
module.exports = class HotModuleReplacementPlugin {
|
module.exports = class HotModuleReplacementPlugin {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
|
@ -198,6 +199,11 @@ module.exports = class HotModuleReplacementPlugin {
|
||||||
parser.plugin("evaluate Identifier module.hot", expr => {
|
parser.plugin("evaluate Identifier module.hot", expr => {
|
||||||
return ParserHelpers.evaluateToIdentifier("module.hot", !!parser.state.compilation.hotUpdateChunkTemplate)(expr);
|
return ParserHelpers.evaluateToIdentifier("module.hot", !!parser.state.compilation.hotUpdateChunkTemplate)(expr);
|
||||||
});
|
});
|
||||||
|
// 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.plugin("call module.hot.accept", expr => {
|
parser.plugin("call module.hot.accept", expr => {
|
||||||
if(!parser.state.compilation.hotUpdateChunkTemplate) return false;
|
if(!parser.state.compilation.hotUpdateChunkTemplate) return false;
|
||||||
if(expr.arguments.length >= 1) {
|
if(expr.arguments.length >= 1) {
|
||||||
|
|
@ -220,9 +226,9 @@ module.exports = class HotModuleReplacementPlugin {
|
||||||
requests.push(request);
|
requests.push(request);
|
||||||
});
|
});
|
||||||
if(expr.arguments.length > 1)
|
if(expr.arguments.length > 1)
|
||||||
parser.applyPluginsBailResult("hot accept callback", expr.arguments[1], requests);
|
parser.hooks.hotAcceptCallback.call(expr.arguments[1], requests);
|
||||||
else
|
else
|
||||||
parser.applyPluginsBailResult("hot accept without callback", expr, requests);
|
parser.hooks.hotAcceptWithoutCallback.call(expr, requests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
182
lib/Parser.js
182
lib/Parser.js
|
|
@ -7,7 +7,9 @@
|
||||||
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
||||||
|
|
||||||
const acorn = require("acorn-dynamic-import").default;
|
const acorn = require("acorn-dynamic-import").default;
|
||||||
const Tapable = require("tapable-old");
|
const Tapable = require("tapable").Tapable;
|
||||||
|
const SyncBailHook = require("tapable").SyncBailHook;
|
||||||
|
const HookMap = require("tapable/lib/HookMap");
|
||||||
const vm = require("vm");
|
const vm = require("vm");
|
||||||
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
||||||
const StackedSetMap = require("./util/StackedSetMap");
|
const StackedSetMap = require("./util/StackedSetMap");
|
||||||
|
|
@ -71,6 +73,75 @@ class TrackingSet {
|
||||||
class Parser extends Tapable {
|
class Parser extends Tapable {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
|
this.hooks = {
|
||||||
|
evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
evaluate: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
evaluateDefinedIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
evaluateCallExpressionMember: new HookMap(() => new SyncBailHook(["expression", "param"])),
|
||||||
|
statement: new SyncBailHook(["statement"]),
|
||||||
|
statementIf: new SyncBailHook(["statement"]),
|
||||||
|
label: new HookMap(() => new SyncBailHook(["statement"])),
|
||||||
|
import: new SyncBailHook(["statement", "source"]),
|
||||||
|
importSpecifier: new SyncBailHook(["statement", "source", "exportName", "identifierName"]),
|
||||||
|
export: new SyncBailHook(["statement"]),
|
||||||
|
exportImport: new SyncBailHook(["statement", "source"]),
|
||||||
|
exportDeclaration: new SyncBailHook(["statement", "declaration"]),
|
||||||
|
exportExpression: new SyncBailHook(["statement", "declaration"]),
|
||||||
|
exportSpecifier: new SyncBailHook(["statement", "identifierName", "exportName", "index"]),
|
||||||
|
exportImportSpecifier: new SyncBailHook(["statement", "source", "identifierName", "exportName", "index"]),
|
||||||
|
varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])),
|
||||||
|
varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
|
||||||
|
varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
|
||||||
|
varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
|
||||||
|
canRename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
||||||
|
rename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
||||||
|
assigned: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
assign: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
typeof: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
expressionConditionalOperator: new SyncBailHook(["expression"]),
|
||||||
|
importCall: new SyncBailHook(["expression"]),
|
||||||
|
call: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
callAnyMember: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
expression: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
expressionAnyMember: new HookMap(() => new SyncBailHook(["expression"])),
|
||||||
|
program: new SyncBailHook(["ast", "comments"]),
|
||||||
|
};
|
||||||
|
const HOOK_MAP_COMPAT_CONFIG = {
|
||||||
|
evaluateTypeof: /^evaluate typeof (.+)$/,
|
||||||
|
evaluateIdentifier: /^evaluate Identifier (.+)$/,
|
||||||
|
evaluateDefinedIdentifier: /^evaluate defined Identifier (.+)$/,
|
||||||
|
evaluateCallExpressionMember: /^evaluate CallExpression .(.+)$/,
|
||||||
|
evaluate: /^evaluate (.+)$/,
|
||||||
|
label: /^label (.+)$/,
|
||||||
|
varDeclarationLet: /^var-let (.+)$/,
|
||||||
|
varDeclarationConst: /^var-const (.+)$/,
|
||||||
|
varDeclarationVar: /^var-var (.+)$/,
|
||||||
|
varDeclaration: /^var (.+)$/,
|
||||||
|
canRename: /^can-rename (.+)$/,
|
||||||
|
rename: /^rename (.+)$/,
|
||||||
|
typeof: /^typeof (.+)$/,
|
||||||
|
assigned: /^assigned (.+)$/,
|
||||||
|
assign: /^assign (.+)$/,
|
||||||
|
expressionConditionalOperator: /^expression \?:$/,
|
||||||
|
callAnyMember: /^call (.+)\.\*$/,
|
||||||
|
call: /^call (.+)$/,
|
||||||
|
expressionAnyMember: /^expression (.+)\.\*$/,
|
||||||
|
expression: /^expression (.+)$/,
|
||||||
|
};
|
||||||
|
this._pluginCompat.tap("Parser", options => {
|
||||||
|
for(const name of Object.keys(HOOK_MAP_COMPAT_CONFIG)) {
|
||||||
|
const regexp = HOOK_MAP_COMPAT_CONFIG[name];
|
||||||
|
const match = regexp.exec(options.name);
|
||||||
|
if(match) {
|
||||||
|
if(match[1])
|
||||||
|
this.hooks[name].tap(match[1], options.fn.name || "unnamed compat plugin", options.fn.bind(this));
|
||||||
|
else
|
||||||
|
this.hooks[name].tap(options.fn.name || "unnamed compat plugin", options.fn.bind(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.scope = undefined;
|
this.scope = undefined;
|
||||||
this.state = undefined;
|
this.state = undefined;
|
||||||
|
|
@ -240,14 +311,14 @@ class Parser extends Tapable {
|
||||||
if(expr.argument.type === "Identifier") {
|
if(expr.argument.type === "Identifier") {
|
||||||
name = this.scope.renames.get(expr.argument.name) || expr.argument.name;
|
name = this.scope.renames.get(expr.argument.name) || expr.argument.name;
|
||||||
if(!this.scope.definitions.has(name)) {
|
if(!this.scope.definitions.has(name)) {
|
||||||
res = this.applyPluginsBailResult1("evaluate typeof " + name, expr);
|
res = this.hooks.evaluateTypeof.for(name).call(expr);
|
||||||
if(res !== undefined) return res;
|
if(res !== undefined) return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(expr.argument.type === "MemberExpression") {
|
if(expr.argument.type === "MemberExpression") {
|
||||||
const exprName = this.getNameForExpression(expr.argument);
|
const exprName = this.getNameForExpression(expr.argument);
|
||||||
if(exprName && exprName.free) {
|
if(exprName && exprName.free) {
|
||||||
res = this.applyPluginsBailResult1("evaluate typeof " + exprName.name, expr);
|
res = this.hooks.evaluateTypeof.for(exprName.name).call(expr);
|
||||||
if(res !== undefined) return res;
|
if(res !== undefined) return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -281,17 +352,17 @@ class Parser extends Tapable {
|
||||||
this.plugin("evaluate Identifier", expr => {
|
this.plugin("evaluate Identifier", expr => {
|
||||||
const name = this.scope.renames.get(expr.name) || expr.name;
|
const name = this.scope.renames.get(expr.name) || expr.name;
|
||||||
if(!this.scope.definitions.has(expr.name)) {
|
if(!this.scope.definitions.has(expr.name)) {
|
||||||
const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr);
|
const result = this.hooks.evaluateIdentifier.for(name).call(expr);
|
||||||
if(result) return result;
|
if(result) return result;
|
||||||
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
|
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
|
||||||
} else {
|
} else {
|
||||||
return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr);
|
return this.hooks.evaluateDefinedIdentifier.for(name).call(expr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.plugin("evaluate ThisExpression", expr => {
|
this.plugin("evaluate ThisExpression", expr => {
|
||||||
const name = this.scope.renames.get("this");
|
const name = this.scope.renames.get("this");
|
||||||
if(name) {
|
if(name) {
|
||||||
const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr);
|
const result = this.hooks.evaluateIdentifier.for(name).call(expr);
|
||||||
if(result) return result;
|
if(result) return result;
|
||||||
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
|
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
|
||||||
}
|
}
|
||||||
|
|
@ -300,11 +371,11 @@ class Parser extends Tapable {
|
||||||
let exprName = this.getNameForExpression(expression);
|
let exprName = this.getNameForExpression(expression);
|
||||||
if(exprName) {
|
if(exprName) {
|
||||||
if(exprName.free) {
|
if(exprName.free) {
|
||||||
const result = this.applyPluginsBailResult1("evaluate Identifier " + exprName.name, expression);
|
const result = this.hooks.evaluateIdentifier.for(exprName.name).call(expression);
|
||||||
if(result) return result;
|
if(result) return result;
|
||||||
return new BasicEvaluatedExpression().setIdentifier(exprName.name).setRange(expression.range);
|
return new BasicEvaluatedExpression().setIdentifier(exprName.name).setRange(expression.range);
|
||||||
} else {
|
} else {
|
||||||
return this.applyPluginsBailResult1("evaluate defined Identifier " + exprName.name, expression);
|
return this.hooks.evaluateDefinedIdentifier.for(exprName.name).call(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -314,7 +385,7 @@ class Parser extends Tapable {
|
||||||
const param = this.evaluateExpression(expr.callee.object);
|
const param = this.evaluateExpression(expr.callee.object);
|
||||||
if(!param) return;
|
if(!param) return;
|
||||||
const property = expr.callee.property.name || expr.callee.property.value;
|
const property = expr.callee.property.name || expr.callee.property.value;
|
||||||
return this.applyPluginsBailResult2("evaluate CallExpression ." + property, expr, param);
|
return this.hooks.evaluateCallExpressionMember.for(property).call(expr, param);
|
||||||
});
|
});
|
||||||
this.plugin("evaluate CallExpression .replace", (expr, param) => {
|
this.plugin("evaluate CallExpression .replace", (expr, param) => {
|
||||||
if(!param.isString()) return;
|
if(!param.isString()) return;
|
||||||
|
|
@ -515,7 +586,7 @@ class Parser extends Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
walkStatement(statement) {
|
walkStatement(statement) {
|
||||||
if(this.applyPluginsBailResult1("statement", statement) !== undefined) return;
|
if(this.hooks.statement.call(statement) !== undefined) return;
|
||||||
const handler = this["walk" + statement.type];
|
const handler = this["walk" + statement.type];
|
||||||
if(handler)
|
if(handler)
|
||||||
handler.call(this, statement);
|
handler.call(this, statement);
|
||||||
|
|
@ -541,7 +612,7 @@ class Parser extends Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
walkIfStatement(statement) {
|
walkIfStatement(statement) {
|
||||||
const result = this.applyPluginsBailResult1("statement if", statement);
|
const result = this.hooks.statementIf.call(statement);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
this.walkExpression(statement.test);
|
this.walkExpression(statement.test);
|
||||||
this.walkStatement(statement.consequent);
|
this.walkStatement(statement.consequent);
|
||||||
|
|
@ -560,7 +631,7 @@ class Parser extends Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
walkLabeledStatement(statement) {
|
walkLabeledStatement(statement) {
|
||||||
const result = this.applyPluginsBailResult1("label " + statement.label.name, statement);
|
const result = this.hooks.label.for(statement.label.name).call(statement);
|
||||||
if(result !== true)
|
if(result !== true)
|
||||||
this.walkStatement(statement.body);
|
this.walkStatement(statement.body);
|
||||||
}
|
}
|
||||||
|
|
@ -708,20 +779,20 @@ class Parser extends Tapable {
|
||||||
|
|
||||||
prewalkImportDeclaration(statement) {
|
prewalkImportDeclaration(statement) {
|
||||||
const source = statement.source.value;
|
const source = statement.source.value;
|
||||||
this.applyPluginsBailResult2("import", statement, source);
|
this.hooks.import.call(statement, source);
|
||||||
statement.specifiers.forEach(specifier => {
|
statement.specifiers.forEach(specifier => {
|
||||||
const name = specifier.local.name;
|
const name = specifier.local.name;
|
||||||
this.scope.renames.set(name, null);
|
this.scope.renames.set(name, null);
|
||||||
this.scope.definitions.add(name);
|
this.scope.definitions.add(name);
|
||||||
switch(specifier.type) {
|
switch(specifier.type) {
|
||||||
case "ImportDefaultSpecifier":
|
case "ImportDefaultSpecifier":
|
||||||
this.applyPluginsBailResult4("import specifier", statement, source, "default", name);
|
this.hooks.importSpecifier.call(statement, source, "default", name);
|
||||||
break;
|
break;
|
||||||
case "ImportSpecifier":
|
case "ImportSpecifier":
|
||||||
this.applyPluginsBailResult4("import specifier", statement, source, specifier.imported.name, name);
|
this.hooks.importSpecifier.call(statement, source, specifier.imported.name, name);
|
||||||
break;
|
break;
|
||||||
case "ImportNamespaceSpecifier":
|
case "ImportNamespaceSpecifier":
|
||||||
this.applyPluginsBailResult4("import specifier", statement, source, null, name);
|
this.hooks.importSpecifier.call(statement, source, null, name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -731,15 +802,15 @@ class Parser extends Tapable {
|
||||||
let source;
|
let source;
|
||||||
if(statement.source) {
|
if(statement.source) {
|
||||||
source = statement.source.value;
|
source = statement.source.value;
|
||||||
this.applyPluginsBailResult2("export import", statement, source);
|
this.hooks.exportImport.call(statement, source);
|
||||||
} else {
|
} else {
|
||||||
this.applyPluginsBailResult1("export", statement);
|
this.hooks.export.call(statement);
|
||||||
}
|
}
|
||||||
if(statement.declaration) {
|
if(statement.declaration) {
|
||||||
if(/Expression$/.test(statement.declaration.type)) {
|
if(/Expression$/.test(statement.declaration.type)) {
|
||||||
throw new Error("Doesn't occur?");
|
throw new Error("Doesn't occur?");
|
||||||
} else {
|
} else {
|
||||||
if(!this.applyPluginsBailResult2("export declaration", statement, statement.declaration)) {
|
if(!this.hooks.exportDeclaration.call(statement, statement.declaration)) {
|
||||||
const originalDefinitions = this.scope.definitions;
|
const originalDefinitions = this.scope.definitions;
|
||||||
const tracker = new TrackingSet(this.scope.definitions);
|
const tracker = new TrackingSet(this.scope.definitions);
|
||||||
this.scope.definitions = tracker;
|
this.scope.definitions = tracker;
|
||||||
|
|
@ -748,7 +819,7 @@ class Parser extends Tapable {
|
||||||
this.scope.definitions = originalDefinitions;
|
this.scope.definitions = originalDefinitions;
|
||||||
for(let index = newDefs.length - 1; index >= 0; index--) {
|
for(let index = newDefs.length - 1; index >= 0; index--) {
|
||||||
const def = newDefs[index];
|
const def = newDefs[index];
|
||||||
this.applyPluginsBailResult4("export specifier", statement, def, def, index);
|
this.hooks.exportSpecifier.call(statement, def, def, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -761,9 +832,9 @@ class Parser extends Tapable {
|
||||||
{
|
{
|
||||||
const name = specifier.exported.name;
|
const name = specifier.exported.name;
|
||||||
if(source)
|
if(source)
|
||||||
this.applyPluginsBailResult5("export import specifier", statement, source, specifier.local.name, name, specifierIndex);
|
this.hooks.exportImportSpecifier.call(statement, source, specifier.local.name, name, specifierIndex);
|
||||||
else
|
else
|
||||||
this.applyPluginsBailResult4("export specifier", statement, specifier.local.name, name, specifierIndex);
|
this.hooks.exportSpecifier.call(statement, specifier.local.name, name, specifierIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -787,29 +858,29 @@ class Parser extends Tapable {
|
||||||
this.scope.definitions = originalDefinitions;
|
this.scope.definitions = originalDefinitions;
|
||||||
for(let index = 0, len = newDefs.length; index < len; index++) {
|
for(let index = 0, len = newDefs.length; index < len; index++) {
|
||||||
const def = newDefs[index];
|
const def = newDefs[index];
|
||||||
this.applyPluginsBailResult3("export specifier", statement, def, "default");
|
this.hooks.exportSpecifier.call(statement, def, "default");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
walkExportDefaultDeclaration(statement) {
|
walkExportDefaultDeclaration(statement) {
|
||||||
this.applyPluginsBailResult1("export", statement);
|
this.hooks.export.call(statement);
|
||||||
if(/Declaration$/.test(statement.declaration.type)) {
|
if(/Declaration$/.test(statement.declaration.type)) {
|
||||||
if(!this.applyPluginsBailResult2("export declaration", statement, statement.declaration)) {
|
if(!this.hooks.exportDeclaration.call(statement, statement.declaration)) {
|
||||||
this.walkStatement(statement.declaration);
|
this.walkStatement(statement.declaration);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.walkExpression(statement.declaration);
|
this.walkExpression(statement.declaration);
|
||||||
if(!this.applyPluginsBailResult2("export expression", statement, statement.declaration)) {
|
if(!this.hooks.exportExpression.call(statement, statement.declaration)) {
|
||||||
this.applyPluginsBailResult3("export specifier", statement, statement.declaration, "default");
|
this.hooks.exportSpecifier.call(statement, statement.declaration, "default");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prewalkExportAllDeclaration(statement) {
|
prewalkExportAllDeclaration(statement) {
|
||||||
const source = statement.source.value;
|
const source = statement.source.value;
|
||||||
this.applyPluginsBailResult2("export import", statement, source);
|
this.hooks.exportImport.call(statement, source);
|
||||||
this.applyPluginsBailResult5("export import specifier", statement, source, null, null, 0);
|
this.hooks.exportImportSpecifier.call(statement, source, null, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
prewalkVariableDeclaration(statement) {
|
prewalkVariableDeclaration(statement) {
|
||||||
|
|
@ -864,8 +935,11 @@ class Parser extends Tapable {
|
||||||
case "VariableDeclarator":
|
case "VariableDeclarator":
|
||||||
{
|
{
|
||||||
this.enterPattern(declarator.id, (name, decl) => {
|
this.enterPattern(declarator.id, (name, decl) => {
|
||||||
if(!this.applyPluginsBailResult1("var-" + declarator.kind + " " + name, decl)) {
|
const hookMap = declarator.kind === "const" ? this.hooks.varDeclarationConst :
|
||||||
if(!this.applyPluginsBailResult1("var " + name, decl)) {
|
declarator.kind === "let" ? this.hooks.varDeclarationLet :
|
||||||
|
this.hooks.varDeclarationVar;
|
||||||
|
if(!hookMap.for(name).call(decl)) {
|
||||||
|
if(!this.hooks.varDeclaration.for(name).call(decl)) {
|
||||||
this.scope.renames.set(name, null);
|
this.scope.renames.set(name, null);
|
||||||
this.scope.definitions.add(name);
|
this.scope.definitions.add(name);
|
||||||
}
|
}
|
||||||
|
|
@ -883,9 +957,9 @@ class Parser extends Tapable {
|
||||||
case "VariableDeclarator":
|
case "VariableDeclarator":
|
||||||
{
|
{
|
||||||
const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);
|
const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);
|
||||||
if(renameIdentifier && declarator.id.type === "Identifier" && this.applyPluginsBailResult1("can-rename " + renameIdentifier, declarator.init)) {
|
if(renameIdentifier && declarator.id.type === "Identifier" && this.hooks.canRename.for(renameIdentifier).call(declarator.init)) {
|
||||||
// renaming with "var a = b;"
|
// renaming with "var a = b;"
|
||||||
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, declarator.init)) {
|
if(!this.hooks.rename.for(renameIdentifier).call(declarator.init)) {
|
||||||
this.scope.renames.set(declarator.id.name, this.scope.renames.get(renameIdentifier) || renameIdentifier);
|
this.scope.renames.set(declarator.id.name, this.scope.renames.get(renameIdentifier) || renameIdentifier);
|
||||||
this.scope.definitions.delete(declarator.id.name);
|
this.scope.definitions.delete(declarator.id.name);
|
||||||
}
|
}
|
||||||
|
|
@ -1019,7 +1093,7 @@ class Parser extends Tapable {
|
||||||
if(expression.operator === "typeof") {
|
if(expression.operator === "typeof") {
|
||||||
const exprName = this.getNameForExpression(expression.argument);
|
const exprName = this.getNameForExpression(expression.argument);
|
||||||
if(exprName && exprName.free) {
|
if(exprName && exprName.free) {
|
||||||
const result = this.applyPluginsBailResult1("typeof " + exprName.name, expression);
|
const result = this.hooks.typeof.for(exprName.name).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1042,18 +1116,18 @@ class Parser extends Tapable {
|
||||||
|
|
||||||
walkAssignmentExpression(expression) {
|
walkAssignmentExpression(expression) {
|
||||||
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
||||||
if(expression.left.type === "Identifier" && renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, expression.right)) {
|
if(expression.left.type === "Identifier" && renameIdentifier && this.hooks.canRename.for(renameIdentifier).call(expression.right)) {
|
||||||
// renaming "a = b;"
|
// renaming "a = b;"
|
||||||
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, expression.right)) {
|
if(!this.hooks.rename.for(renameIdentifier).call(expression.right)) {
|
||||||
this.scope.renames.set(expression.left.name, renameIdentifier);
|
this.scope.renames.set(expression.left.name, renameIdentifier);
|
||||||
this.scope.definitions.delete(expression.left.name);
|
this.scope.definitions.delete(expression.left.name);
|
||||||
}
|
}
|
||||||
} else if(expression.left.type === "Identifier") {
|
} else if(expression.left.type === "Identifier") {
|
||||||
if(!this.applyPluginsBailResult1("assigned " + expression.left.name, expression)) {
|
if(!this.hooks.assigned.for(expression.left.name).call(expression)) {
|
||||||
this.walkExpression(expression.right);
|
this.walkExpression(expression.right);
|
||||||
}
|
}
|
||||||
this.scope.renames.set(expression.left.name, null);
|
this.scope.renames.set(expression.left.name, null);
|
||||||
if(!this.applyPluginsBailResult1("assign " + expression.left.name, expression)) {
|
if(!this.hooks.assign.for(expression.left.name).call(expression)) {
|
||||||
this.walkExpression(expression.left);
|
this.walkExpression(expression.left);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1066,7 +1140,7 @@ class Parser extends Tapable {
|
||||||
}
|
}
|
||||||
|
|
||||||
walkConditionalExpression(expression) {
|
walkConditionalExpression(expression) {
|
||||||
const result = this.applyPluginsBailResult1("expression ?:", expression);
|
const result = this.hooks.expressionConditionalOperator.call(expression);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
this.walkExpression(expression.test);
|
this.walkExpression(expression.test);
|
||||||
this.walkExpression(expression.consequent);
|
this.walkExpression(expression.consequent);
|
||||||
|
|
@ -1113,8 +1187,8 @@ class Parser extends Tapable {
|
||||||
const walkIIFE = (functionExpression, options, currentThis) => {
|
const walkIIFE = (functionExpression, options, currentThis) => {
|
||||||
const renameArgOrThis = argOrThis => {
|
const renameArgOrThis = argOrThis => {
|
||||||
const renameIdentifier = this.getRenameIdentifier(argOrThis);
|
const renameIdentifier = this.getRenameIdentifier(argOrThis);
|
||||||
if(renameIdentifier && this.applyPluginsBailResult1("can-rename " + renameIdentifier, argOrThis)) {
|
if(renameIdentifier && this.hooks.canRename.for(renameIdentifier).call(argOrThis)) {
|
||||||
if(!this.applyPluginsBailResult1("rename " + renameIdentifier, argOrThis))
|
if(!this.hooks.rename.for(renameIdentifier).call(argOrThis))
|
||||||
return renameIdentifier;
|
return renameIdentifier;
|
||||||
}
|
}
|
||||||
this.walkExpression(argOrThis);
|
this.walkExpression(argOrThis);
|
||||||
|
|
@ -1152,7 +1226,7 @@ class Parser extends Tapable {
|
||||||
// (function(...) { }(...))
|
// (function(...) { }(...))
|
||||||
walkIIFE.call(this, expression.callee, expression.arguments);
|
walkIIFE.call(this, expression.callee, expression.arguments);
|
||||||
} else if(expression.callee.type === "Import") {
|
} else if(expression.callee.type === "Import") {
|
||||||
result = this.applyPluginsBailResult1("import-call", expression);
|
result = this.hooks.importCall.call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1162,12 +1236,12 @@ class Parser extends Tapable {
|
||||||
|
|
||||||
const callee = this.evaluateExpression(expression.callee);
|
const callee = this.evaluateExpression(expression.callee);
|
||||||
if(callee.isIdentifier()) {
|
if(callee.isIdentifier()) {
|
||||||
result = this.applyPluginsBailResult1("call " + callee.identifier, expression);
|
result = this.hooks.call.for(callee.identifier).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
let identifier = callee.identifier.replace(/\.[^.]+$/, ".*");
|
let identifier = callee.identifier.replace(/\.[^.]+$/, "");
|
||||||
if(identifier !== callee.identifier) {
|
if(identifier !== callee.identifier) {
|
||||||
result = this.applyPluginsBailResult1("call " + identifier, expression);
|
result = this.hooks.callAnyMember.for(identifier).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1183,10 +1257,10 @@ class Parser extends Tapable {
|
||||||
walkMemberExpression(expression) {
|
walkMemberExpression(expression) {
|
||||||
const exprName = this.getNameForExpression(expression);
|
const exprName = this.getNameForExpression(expression);
|
||||||
if(exprName && exprName.free) {
|
if(exprName && exprName.free) {
|
||||||
let result = this.applyPluginsBailResult1("expression " + exprName.name, expression);
|
let result = this.hooks.expression.for(exprName.name).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
result = this.applyPluginsBailResult1("expression " + exprName.nameGeneral, expression);
|
result = this.hooks.expressionAnyMember.for(exprName.nameGeneral).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1197,7 +1271,7 @@ class Parser extends Tapable {
|
||||||
|
|
||||||
walkIdentifier(expression) {
|
walkIdentifier(expression) {
|
||||||
if(!this.scope.definitions.has(expression.name)) {
|
if(!this.scope.definitions.has(expression.name)) {
|
||||||
const result = this.applyPluginsBailResult1("expression " + (this.scope.renames.get(expression.name) || expression.name), expression);
|
const result = this.hooks.expression.for(this.scope.renames.get(expression.name) || expression.name).call(expression);
|
||||||
if(result === true)
|
if(result === true)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1265,7 +1339,7 @@ class Parser extends Tapable {
|
||||||
|
|
||||||
evaluateExpression(expression) {
|
evaluateExpression(expression) {
|
||||||
try {
|
try {
|
||||||
const result = this.applyPluginsBailResult1("evaluate " + expression.type, expression);
|
const result = this.hooks.evaluate.for(expression.type).call(expression);
|
||||||
if(result !== undefined)
|
if(result !== undefined)
|
||||||
return result;
|
return result;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|
@ -1415,7 +1489,7 @@ class Parser extends Tapable {
|
||||||
};
|
};
|
||||||
const state = this.state = initialState || {};
|
const state = this.state = initialState || {};
|
||||||
this.comments = comments;
|
this.comments = comments;
|
||||||
if(this.applyPluginsBailResult2("program", ast, comments) === undefined) {
|
if(this.hooks.program.call(ast, comments) === undefined) {
|
||||||
this.prewalkStatements(ast.body);
|
this.prewalkStatements(ast.body);
|
||||||
this.walkStatements(ast.body);
|
this.walkStatements(ast.body);
|
||||||
}
|
}
|
||||||
|
|
@ -1481,10 +1555,12 @@ class Parser extends Tapable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let prefix = "";
|
let prefix = "";
|
||||||
for(let i = exprName.length - 1; i >= 1; i--)
|
for(let i = exprName.length - 1; i >= 2; i--)
|
||||||
prefix += exprName[i] + ".";
|
prefix += exprName[i] + ".";
|
||||||
const name = prefix + exprName[0];
|
if(exprName.length > 1)
|
||||||
const nameGeneral = prefix + "*";
|
prefix += exprName[1];
|
||||||
|
const name = prefix ? prefix + "." + exprName[0] : exprName[0];
|
||||||
|
const nameGeneral = prefix;
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
nameGeneral,
|
nameGeneral,
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,83 @@ class AMDDefineDependencyParserPlugin {
|
||||||
|
|
||||||
apply(parser) {
|
apply(parser) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
|
|
||||||
|
const processArray = (expr, param, identifiers, namedModule) => {
|
||||||
|
if(param.isArray()) {
|
||||||
|
param.items.forEach((param, idx) => {
|
||||||
|
if(param.isString() && ["require", "module", "exports"].indexOf(param.string) >= 0)
|
||||||
|
identifiers[idx] = param.string;
|
||||||
|
const result = processItem(expr, param, namedModule);
|
||||||
|
if(result === undefined) {
|
||||||
|
processContext(expr, param);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if(param.isConstArray()) {
|
||||||
|
const deps = [];
|
||||||
|
param.array.forEach((request, idx) => {
|
||||||
|
let dep;
|
||||||
|
let localModule;
|
||||||
|
if(request === "require") {
|
||||||
|
identifiers[idx] = request;
|
||||||
|
dep = "__webpack_require__";
|
||||||
|
} else if(["exports", "module"].indexOf(request) >= 0) {
|
||||||
|
identifiers[idx] = request;
|
||||||
|
dep = request;
|
||||||
|
} else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, request)) { // eslint-disable-line no-cond-assign
|
||||||
|
dep = new LocalModuleDependency(localModule);
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
} else {
|
||||||
|
dep = new AMDRequireItemDependency(request);
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
}
|
||||||
|
deps.push(dep);
|
||||||
|
});
|
||||||
|
const dep = new AMDRequireArrayDependency(deps, param.range);
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const processItem = (expr, param, namedModule) => {
|
||||||
|
if(param.isConditional()) {
|
||||||
|
param.options.forEach((param) => {
|
||||||
|
const result = processItem(expr, param);
|
||||||
|
if(result === undefined) {
|
||||||
|
processContext(expr, param);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if(param.isString()) {
|
||||||
|
let dep, localModule;
|
||||||
|
if(param.string === "require") {
|
||||||
|
dep = new ConstDependency("__webpack_require__", param.range);
|
||||||
|
} else if(["require", "exports", "module"].indexOf(param.string) >= 0) {
|
||||||
|
dep = new ConstDependency(param.string, param.range);
|
||||||
|
} else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, param.string, namedModule)) { // eslint-disable-line no-cond-assign
|
||||||
|
dep = new LocalModuleDependency(localModule, param.range);
|
||||||
|
} else {
|
||||||
|
dep = new AMDRequireItemDependency(param.string, param.range);
|
||||||
|
}
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const processContext = (expr, param) => {
|
||||||
|
const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
|
||||||
|
if(!dep) return;
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
parser.plugin("call define", (expr) => {
|
parser.plugin("call define", (expr) => {
|
||||||
let array, fn, obj, namedModule;
|
let array, fn, obj, namedModule;
|
||||||
switch(expr.arguments.length) {
|
switch(expr.arguments.length) {
|
||||||
|
|
@ -126,7 +203,7 @@ class AMDDefineDependencyParserPlugin {
|
||||||
if(array) {
|
if(array) {
|
||||||
identifiers = {};
|
identifiers = {};
|
||||||
const param = parser.evaluateExpression(array);
|
const param = parser.evaluateExpression(array);
|
||||||
const result = parser.applyPluginsBailResult("call define:amd:array", expr, param, identifiers, namedModule);
|
const result = processArray(expr, param, identifiers, namedModule);
|
||||||
if(!result) return;
|
if(!result) return;
|
||||||
if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
|
if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
|
||||||
if(identifiers[idx]) {
|
if(identifiers[idx]) {
|
||||||
|
|
@ -186,81 +263,6 @@ class AMDDefineDependencyParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
parser.plugin("call define:amd:array", (expr, param, identifiers, namedModule) => {
|
|
||||||
if(param.isArray()) {
|
|
||||||
param.items.forEach((param, idx) => {
|
|
||||||
if(param.isString() && ["require", "module", "exports"].indexOf(param.string) >= 0)
|
|
||||||
identifiers[idx] = param.string;
|
|
||||||
const result = parser.applyPluginsBailResult("call define:amd:item", expr, param, namedModule);
|
|
||||||
if(result === undefined) {
|
|
||||||
parser.applyPluginsBailResult("call define:amd:context", expr, param);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} else if(param.isConstArray()) {
|
|
||||||
const deps = [];
|
|
||||||
param.array.forEach((request, idx) => {
|
|
||||||
let dep;
|
|
||||||
let localModule;
|
|
||||||
if(request === "require") {
|
|
||||||
identifiers[idx] = request;
|
|
||||||
dep = "__webpack_require__";
|
|
||||||
} else if(["exports", "module"].indexOf(request) >= 0) {
|
|
||||||
identifiers[idx] = request;
|
|
||||||
dep = request;
|
|
||||||
} else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, request)) { // eslint-disable-line no-cond-assign
|
|
||||||
dep = new LocalModuleDependency(localModule);
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
} else {
|
|
||||||
dep = new AMDRequireItemDependency(request);
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
}
|
|
||||||
deps.push(dep);
|
|
||||||
});
|
|
||||||
const dep = new AMDRequireArrayDependency(deps, param.range);
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
parser.plugin("call define:amd:item", (expr, param, namedModule) => {
|
|
||||||
if(param.isConditional()) {
|
|
||||||
param.options.forEach((param) => {
|
|
||||||
const result = parser.applyPluginsBailResult("call define:amd:item", expr, param);
|
|
||||||
if(result === undefined) {
|
|
||||||
parser.applyPluginsBailResult("call define:amd:context", expr, param);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} else if(param.isString()) {
|
|
||||||
let dep, localModule;
|
|
||||||
if(param.string === "require") {
|
|
||||||
dep = new ConstDependency("__webpack_require__", param.range);
|
|
||||||
} else if(["require", "exports", "module"].indexOf(param.string) >= 0) {
|
|
||||||
dep = new ConstDependency(param.string, param.range);
|
|
||||||
} else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, param.string, namedModule)) { // eslint-disable-line no-cond-assign
|
|
||||||
dep = new LocalModuleDependency(localModule, param.range);
|
|
||||||
} else {
|
|
||||||
dep = new AMDRequireItemDependency(param.string, param.range);
|
|
||||||
}
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
parser.plugin("call define:amd:context", (expr, param) => {
|
|
||||||
const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
|
|
||||||
if(!dep) return;
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = AMDDefineDependencyParserPlugin;
|
module.exports = AMDDefineDependencyParserPlugin;
|
||||||
|
|
|
||||||
|
|
@ -45,67 +45,13 @@ class AMDRequireDependenciesBlockParserPlugin {
|
||||||
|
|
||||||
apply(parser) {
|
apply(parser) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
parser.plugin("call require", (expr) => {
|
|
||||||
let param;
|
|
||||||
let dep;
|
|
||||||
let result;
|
|
||||||
|
|
||||||
const old = parser.state.current;
|
const processArray = (expr, param) => {
|
||||||
|
|
||||||
if(expr.arguments.length >= 1) {
|
|
||||||
param = parser.evaluateExpression(expr.arguments[0]);
|
|
||||||
dep = new AMDRequireDependenciesBlock(
|
|
||||||
expr,
|
|
||||||
param.range,
|
|
||||||
(expr.arguments.length > 1) ? expr.arguments[1].range : null,
|
|
||||||
(expr.arguments.length > 2) ? expr.arguments[2].range : null,
|
|
||||||
parser.state.module,
|
|
||||||
expr.loc
|
|
||||||
);
|
|
||||||
parser.state.current = dep;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(expr.arguments.length === 1) {
|
|
||||||
parser.inScope([], () => {
|
|
||||||
result = parser.applyPluginsBailResult("call require:amd:array", expr, param);
|
|
||||||
});
|
|
||||||
parser.state.current = old;
|
|
||||||
if(!result) return;
|
|
||||||
parser.state.current.addBlock(dep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(expr.arguments.length === 2 || expr.arguments.length === 3) {
|
|
||||||
try {
|
|
||||||
parser.inScope([], () => {
|
|
||||||
result = parser.applyPluginsBailResult("call require:amd:array", expr, param);
|
|
||||||
});
|
|
||||||
if(!result) {
|
|
||||||
dep = new UnsupportedDependency("unsupported", expr.range);
|
|
||||||
old.addDependency(dep);
|
|
||||||
if(parser.state.module)
|
|
||||||
parser.state.module.errors.push(new UnsupportedFeatureWarning(parser.state.module, "Cannot statically analyse 'require(..., ...)' in line " + expr.loc.start.line));
|
|
||||||
dep = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
dep.functionBindThis = this.processFunctionArgument(parser, expr.arguments[1]);
|
|
||||||
if(expr.arguments.length === 3) {
|
|
||||||
dep.errorCallbackBindThis = this.processFunctionArgument(parser, expr.arguments[2]);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
parser.state.current = old;
|
|
||||||
if(dep)
|
|
||||||
parser.state.current.addBlock(dep);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
parser.plugin("call require:amd:array", (expr, param) => {
|
|
||||||
if(param.isArray()) {
|
if(param.isArray()) {
|
||||||
param.items.forEach((param) => {
|
param.items.forEach((param) => {
|
||||||
const result = parser.applyPluginsBailResult("call require:amd:item", expr, param);
|
const result = processItem(expr, param);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
parser.applyPluginsBailResult("call require:amd:context", expr, param);
|
processContext(expr, param);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -135,13 +81,13 @@ class AMDRequireDependenciesBlockParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
parser.plugin("call require:amd:item", (expr, param) => {
|
const processItem = (expr, param) => {
|
||||||
if(param.isConditional()) {
|
if(param.isConditional()) {
|
||||||
param.options.forEach((param) => {
|
param.options.forEach((param) => {
|
||||||
const result = parser.applyPluginsBailResult("call require:amd:item", expr, param);
|
const result = processItem(expr, param);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
parser.applyPluginsBailResult("call require:amd:context", expr, param);
|
processContext(expr, param);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -163,14 +109,70 @@ class AMDRequireDependenciesBlockParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
parser.plugin("call require:amd:context", (expr, param) => {
|
const processContext = (expr, param) => {
|
||||||
const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
|
const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
|
||||||
if(!dep) return;
|
if(!dep) return;
|
||||||
dep.loc = expr.loc;
|
dep.loc = expr.loc;
|
||||||
dep.optional = !!parser.scope.inTry;
|
dep.optional = !!parser.scope.inTry;
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.plugin("call require", (expr) => {
|
||||||
|
let param;
|
||||||
|
let dep;
|
||||||
|
let result;
|
||||||
|
|
||||||
|
const old = parser.state.current;
|
||||||
|
|
||||||
|
if(expr.arguments.length >= 1) {
|
||||||
|
param = parser.evaluateExpression(expr.arguments[0]);
|
||||||
|
dep = new AMDRequireDependenciesBlock(
|
||||||
|
expr,
|
||||||
|
param.range,
|
||||||
|
(expr.arguments.length > 1) ? expr.arguments[1].range : null,
|
||||||
|
(expr.arguments.length > 2) ? expr.arguments[2].range : null,
|
||||||
|
parser.state.module,
|
||||||
|
expr.loc
|
||||||
|
);
|
||||||
|
parser.state.current = dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expr.arguments.length === 1) {
|
||||||
|
parser.inScope([], () => {
|
||||||
|
result = processArray(expr, param);
|
||||||
|
});
|
||||||
|
parser.state.current = old;
|
||||||
|
if(!result) return;
|
||||||
|
parser.state.current.addBlock(dep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expr.arguments.length === 2 || expr.arguments.length === 3) {
|
||||||
|
try {
|
||||||
|
parser.inScope([], () => {
|
||||||
|
result = processArray(expr, param);
|
||||||
|
});
|
||||||
|
if(!result) {
|
||||||
|
dep = new UnsupportedDependency("unsupported", expr.range);
|
||||||
|
old.addDependency(dep);
|
||||||
|
if(parser.state.module)
|
||||||
|
parser.state.module.errors.push(new UnsupportedFeatureWarning(parser.state.module, "Cannot statically analyse 'require(..., ...)' in line " + expr.loc.start.line));
|
||||||
|
dep = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
dep.functionBindThis = this.processFunctionArgument(parser, expr.arguments[1]);
|
||||||
|
if(expr.arguments.length === 3) {
|
||||||
|
dep.errorCallbackBindThis = this.processFunctionArgument(parser, expr.arguments[2]);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
parser.state.current = old;
|
||||||
|
if(dep)
|
||||||
|
parser.state.current.addBlock(dep);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,25 @@ class CommonJsRequireDependencyParserPlugin {
|
||||||
|
|
||||||
apply(parser) {
|
apply(parser) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
|
|
||||||
|
const processItem = (expr, param) => {
|
||||||
|
if(param.isString()) {
|
||||||
|
const dep = new CommonJsRequireDependency(param.string, param.range);
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const processContext = (expr, param) => {
|
||||||
|
const dep = ContextDependencyHelpers.create(CommonJsRequireContextDependency, expr.range, param, expr, options);
|
||||||
|
if(!dep) return;
|
||||||
|
dep.loc = expr.loc;
|
||||||
|
dep.optional = !!parser.scope.inTry;
|
||||||
|
parser.state.current.addDependency(dep);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
parser.plugin("expression require.cache", ParserHelpers.toConstantDependency("__webpack_require__.c"));
|
parser.plugin("expression require.cache", ParserHelpers.toConstantDependency("__webpack_require__.c"));
|
||||||
parser.plugin("expression require", (expr) => {
|
parser.plugin("expression require", (expr) => {
|
||||||
const dep = new CommonJsRequireContextDependency({
|
const dep = new CommonJsRequireContextDependency({
|
||||||
|
|
@ -44,7 +63,7 @@ class CommonJsRequireDependencyParserPlugin {
|
||||||
dep.loc = expr.loc;
|
dep.loc = expr.loc;
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
param.options.forEach(param => {
|
param.options.forEach(param => {
|
||||||
const result = parser.applyPluginsBailResult("call require:commonjs:item", expr, param);
|
const result = processItem(expr, param);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
isExpression = true;
|
isExpression = true;
|
||||||
}
|
}
|
||||||
|
|
@ -61,9 +80,9 @@ class CommonJsRequireDependencyParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const result = parser.applyPluginsBailResult("call require:commonjs:item", expr, param);
|
const result = processItem(expr, param);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
parser.applyPluginsBailResult("call require:commonjs:context", expr, param);
|
processContext(expr, param);
|
||||||
} else {
|
} else {
|
||||||
const dep = new RequireHeaderDependency(expr.callee.range);
|
const dep = new RequireHeaderDependency(expr.callee.range);
|
||||||
dep.loc = expr.loc;
|
dep.loc = expr.loc;
|
||||||
|
|
@ -72,23 +91,6 @@ class CommonJsRequireDependencyParserPlugin {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
parser.plugin("call require:commonjs:item", (expr, param) => {
|
|
||||||
if(param.isString()) {
|
|
||||||
const dep = new CommonJsRequireDependency(param.string, param.range);
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
parser.plugin("call require:commonjs:context", (expr, param) => {
|
|
||||||
const dep = ContextDependencyHelpers.create(CommonJsRequireContextDependency, expr.range, param, expr, options);
|
|
||||||
if(!dep) return;
|
|
||||||
dep.loc = expr.loc;
|
|
||||||
dep.optional = !!parser.scope.inTry;
|
|
||||||
parser.state.current.addDependency(dep);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = CommonJsRequireDependencyParserPlugin;
|
module.exports = CommonJsRequireDependencyParserPlugin;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend
|
||||||
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
|
||||||
const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
|
||||||
const ConstDependency = require("./ConstDependency");
|
const ConstDependency = require("./ConstDependency");
|
||||||
|
const SyncBailHook = require("tapable").SyncBailHook;
|
||||||
|
|
||||||
module.exports = class HarmonyImportDependencyParserPlugin {
|
module.exports = class HarmonyImportDependencyParserPlugin {
|
||||||
constructor(moduleOptions) {
|
constructor(moduleOptions) {
|
||||||
|
|
@ -97,6 +98,11 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||||
parser.walkExpressions(args);
|
parser.walkExpressions(args);
|
||||||
return true;
|
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.plugin("hot accept callback", (expr, requests) => {
|
parser.plugin("hot accept callback", (expr, requests) => {
|
||||||
const dependencies = requests
|
const dependencies = requests
|
||||||
.map(request => {
|
.map(request => {
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,15 @@ class RequireResolveDependencyParserPlugin {
|
||||||
|
|
||||||
apply(parser) {
|
apply(parser) {
|
||||||
const options = this.options;
|
const options = this.options;
|
||||||
parser.plugin("call require.resolve", (expr) => {
|
|
||||||
return parser.applyPluginsBailResult("call require.resolve(Weak)", expr, false);
|
const process = (expr, weak) => {
|
||||||
});
|
|
||||||
parser.plugin("call require.resolveWeak", (expr) => {
|
|
||||||
return parser.applyPluginsBailResult("call require.resolve(Weak)", expr, true);
|
|
||||||
});
|
|
||||||
parser.plugin("call require.resolve(Weak)", (expr, weak) => {
|
|
||||||
if(expr.arguments.length !== 1) return;
|
if(expr.arguments.length !== 1) return;
|
||||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||||
if(param.isConditional()) {
|
if(param.isConditional()) {
|
||||||
param.options.forEach((option) => {
|
param.options.forEach((option) => {
|
||||||
const result = parser.applyPluginsBailResult("call require.resolve(Weak):item", expr, option, weak);
|
const result = processItem(expr, option, weak);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
parser.applyPluginsBailResult("call require.resolve(Weak):context", expr, option, weak);
|
processContext(expr, option, weak);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||||
|
|
@ -37,17 +32,17 @@ class RequireResolveDependencyParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const result = parser.applyPluginsBailResult("call require.resolve(Weak):item", expr, param, weak);
|
const result = processItem(expr, param, weak);
|
||||||
if(result === undefined) {
|
if(result === undefined) {
|
||||||
parser.applyPluginsBailResult("call require.resolve(Weak):context", expr, param, weak);
|
processContext(expr, param, weak);
|
||||||
}
|
}
|
||||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||||
dep.loc = expr.loc;
|
dep.loc = expr.loc;
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
parser.plugin("call require.resolve(Weak):item", (expr, param, weak) => {
|
const processItem = (expr, param, weak) => {
|
||||||
if(param.isString()) {
|
if(param.isString()) {
|
||||||
const dep = new RequireResolveDependency(param.string, param.range);
|
const dep = new RequireResolveDependency(param.string, param.range);
|
||||||
dep.loc = expr.loc;
|
dep.loc = expr.loc;
|
||||||
|
|
@ -56,8 +51,8 @@ class RequireResolveDependencyParserPlugin {
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
parser.plugin("call require.resolve(Weak):context", (expr, param, weak) => {
|
const processContext = (expr, param, weak) => {
|
||||||
const dep = ContextDependencyHelpers.create(RequireResolveContextDependency, param.range, param, expr, options, {
|
const dep = ContextDependencyHelpers.create(RequireResolveContextDependency, param.range, param, expr, options, {
|
||||||
mode: weak ? "weak" : "sync"
|
mode: weak ? "weak" : "sync"
|
||||||
});
|
});
|
||||||
|
|
@ -66,6 +61,13 @@ class RequireResolveDependencyParserPlugin {
|
||||||
dep.optional = !!parser.scope.inTry;
|
dep.optional = !!parser.scope.inTry;
|
||||||
parser.state.current.addDependency(dep);
|
parser.state.current.addDependency(dep);
|
||||||
return true;
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.plugin("call require.resolve", (expr) => {
|
||||||
|
return process(expr, false);
|
||||||
|
});
|
||||||
|
parser.plugin("call require.resolveWeak", (expr) => {
|
||||||
|
return process(expr, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
it("should name require in define correctly", function() {
|
||||||
|
define(["require"], function(require) {
|
||||||
|
(typeof require).should.be.eql("function");
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue