Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100978660
CommonJsImportsParserPlugin.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Feb 4, 11:51
Size
10 KB
Mime Type
text/x-c++
Expires
Thu, Feb 6, 11:51 (2 d)
Engine
blob
Format
Raw Data
Handle
24062296
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
CommonJsImportsParserPlugin.js
View Options
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const {
evaluateToIdentifier,
evaluateToString,
expressionIsUnsupported,
toConstantDependency
} = require("../javascript/JavascriptParserHelpers");
const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
const CommonJsRequireDependency = require("./CommonJsRequireDependency");
const ConstDependency = require("./ConstDependency");
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
const LocalModuleDependency = require("./LocalModuleDependency");
const { getLocalModule } = require("./LocalModulesHelpers");
const RequireHeaderDependency = require("./RequireHeaderDependency");
const RequireResolveContextDependency = require("./RequireResolveContextDependency");
const RequireResolveDependency = require("./RequireResolveDependency");
const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
class CommonJsImportsParserPlugin {
constructor(options) {
this.options = options;
}
apply(parser) {
const options = this.options;
// metadata //
const tapRequireExpression = (expression, getMembers) => {
parser.hooks.typeof
.for(expression)
.tap(
"CommonJsPlugin",
toConstantDependency(parser, JSON.stringify("function"))
);
parser.hooks.evaluateTypeof
.for(expression)
.tap("CommonJsPlugin", evaluateToString("function"));
parser.hooks.evaluateIdentifier
.for(expression)
.tap(
"CommonJsPlugin",
evaluateToIdentifier(expression, "require", getMembers, true)
);
};
tapRequireExpression("require", () => []);
tapRequireExpression("require.resolve", () => ["resolve"]);
tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
// Weird stuff //
parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => {
// to not leak to global "require", we need to define a local require here.
const dep = new ConstDependency("var require;", 0);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
});
// Unsupported //
parser.hooks.expression
.for("require.main.require")
.tap(
"CommonJsPlugin",
expressionIsUnsupported(
parser,
"require.main.require is not supported by webpack."
)
);
parser.hooks.call
.for("require.main.require")
.tap(
"CommonJsPlugin",
expressionIsUnsupported(
parser,
"require.main.require is not supported by webpack."
)
);
parser.hooks.expression
.for("module.parent.require")
.tap(
"CommonJsPlugin",
expressionIsUnsupported(
parser,
"module.parent.require is not supported by webpack."
)
);
parser.hooks.call
.for("module.parent.require")
.tap(
"CommonJsPlugin",
expressionIsUnsupported(
parser,
"module.parent.require is not supported by webpack."
)
);
// renaming //
parser.hooks.canRename.for("require").tap("CommonJsPlugin", () => true);
parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => {
// To avoid "not defined" error, replace the value with undefined
const dep = new ConstDependency("undefined", expr.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return false;
});
// inspection //
parser.hooks.expression
.for("require.cache")
.tap(
"CommonJsImportsParserPlugin",
toConstantDependency(parser, RuntimeGlobals.moduleCache, [
RuntimeGlobals.moduleCache,
RuntimeGlobals.moduleId,
RuntimeGlobals.moduleLoaded
])
);
// require as expression //
parser.hooks.expression
.for("require")
.tap("CommonJsImportsParserPlugin", expr => {
const dep = new CommonJsRequireContextDependency(
{
request: options.unknownContextRequest,
recursive: options.unknownContextRecursive,
regExp: options.unknownContextRegExp,
mode: "sync"
},
expr.range
);
dep.critical =
options.unknownContextCritical &&
"require function is used in a way in which dependencies cannot be statically extracted";
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
});
// require //
const processRequireItem = (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 processRequireContext = (expr, param) => {
const dep = ContextDependencyHelpers.create(
CommonJsRequireContextDependency,
expr.range,
param,
expr,
options,
{
category: "commonjs"
},
parser
);
if (!dep) return;
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
};
const createRequireHandler = callNew => expr => {
if (expr.arguments.length !== 1) return;
let localModule;
const param = parser.evaluateExpression(expr.arguments[0]);
if (param.isConditional()) {
let isExpression = false;
for (const p of param.options) {
const result = processRequireItem(expr, p);
if (result === undefined) {
isExpression = true;
}
}
if (!isExpression) {
const dep = new RequireHeaderDependency(expr.callee.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
}
}
if (
param.isString() &&
(localModule = getLocalModule(parser.state, param.string))
) {
localModule.flagUsed();
const dep = new LocalModuleDependency(localModule, expr.range, callNew);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
} else {
const result = processRequireItem(expr, param);
if (result === undefined) {
processRequireContext(expr, param);
} else {
const dep = new RequireHeaderDependency(expr.callee.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
}
return true;
}
};
parser.hooks.call
.for("require")
.tap("CommonJsImportsParserPlugin", createRequireHandler(false));
parser.hooks.new
.for("require")
.tap("CommonJsImportsParserPlugin", createRequireHandler(true));
parser.hooks.call
.for("module.require")
.tap("CommonJsImportsParserPlugin", createRequireHandler(false));
parser.hooks.new
.for("module.require")
.tap("CommonJsImportsParserPlugin", createRequireHandler(true));
// require with property access //
const chainHandler = (expr, calleeMembers, callExpr, members) => {
if (callExpr.arguments.length !== 1) return;
const param = parser.evaluateExpression(callExpr.arguments[0]);
if (param.isString() && !getLocalModule(parser.state, param.string)) {
const dep = new CommonJsFullRequireDependency(
param.string,
expr.range,
members
);
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
dep.optional = !!parser.scope.inTry;
dep.loc = expr.loc;
parser.state.module.addDependency(dep);
return true;
}
};
const callChainHandler = (expr, calleeMembers, callExpr, members) => {
if (callExpr.arguments.length !== 1) return;
const param = parser.evaluateExpression(callExpr.arguments[0]);
if (param.isString() && !getLocalModule(parser.state, param.string)) {
const dep = new CommonJsFullRequireDependency(
param.string,
expr.callee.range,
members
);
dep.call = true;
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
dep.optional = !!parser.scope.inTry;
dep.loc = expr.callee.loc;
parser.state.module.addDependency(dep);
parser.walkExpressions(expr.arguments);
return true;
}
};
parser.hooks.memberChainOfCallMemberChain
.for("require")
.tap("CommonJsImportsParserPlugin", chainHandler);
parser.hooks.memberChainOfCallMemberChain
.for("module.require")
.tap("CommonJsImportsParserPlugin", chainHandler);
parser.hooks.callMemberChainOfCallMemberChain
.for("require")
.tap("CommonJsImportsParserPlugin", callChainHandler);
parser.hooks.callMemberChainOfCallMemberChain
.for("module.require")
.tap("CommonJsImportsParserPlugin", callChainHandler);
// require.resolve //
const processResolve = (expr, weak) => {
if (expr.arguments.length !== 1) return;
const param = parser.evaluateExpression(expr.arguments[0]);
if (param.isConditional()) {
for (const option of param.options) {
const result = processResolveItem(expr, option, weak);
if (result === undefined) {
processResolveContext(expr, option, weak);
}
}
const dep = new RequireResolveHeaderDependency(expr.callee.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
} else {
const result = processResolveItem(expr, param, weak);
if (result === undefined) {
processResolveContext(expr, param, weak);
}
const dep = new RequireResolveHeaderDependency(expr.callee.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
}
};
const processResolveItem = (expr, param, weak) => {
if (param.isString()) {
const dep = new RequireResolveDependency(param.string, param.range);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
dep.weak = weak;
parser.state.current.addDependency(dep);
return true;
}
};
const processResolveContext = (expr, param, weak) => {
const dep = ContextDependencyHelpers.create(
RequireResolveContextDependency,
param.range,
param,
expr,
options,
{
category: "commonjs",
mode: weak ? "weak" : "sync"
},
parser
);
if (!dep) return;
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
};
parser.hooks.call
.for("require.resolve")
.tap("RequireResolveDependencyParserPlugin", expr => {
return processResolve(expr, false);
});
parser.hooks.call
.for("require.resolveWeak")
.tap("RequireResolveDependencyParserPlugin", expr => {
return processResolve(expr, true);
});
}
}
module.exports = CommonJsImportsParserPlugin;
Event Timeline
Log In to Comment