Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
properties: true,
wildcard: false
}, opts)
var state = {
undeclared: {},
undeclaredProps: {},
identifiers: opts.identifiers,
properties: opts.properties,
wildcard: opts.wildcard
}
// Parse if `src` is not already an AST.
var ast = typeof src === 'object' && src !== null && typeof src.type === 'string'
? src
: acorn.parse(src)
var parents = []
dash(ast, {
enter: function (node, parent) {
if (parent) parents.push(parent)
var visit = scopeVisitor[node.type]
if (visit) visit(node, state, parents)
},
leave: function (node, parent) {
var visit = bindingVisitor[node.type]
if (visit) visit(node, state, parents)
if (parent) parents.pop()
}
})
return {
function parse (src, opts) {
if (!opts) opts = {};
var acornOpts = {
ranges: defined(opts.ranges, opts.range),
locations: defined(opts.locations, opts.loc),
allowReserved: defined(opts.allowReserved, true),
allowImportExportEverywhere: defined(opts.allowImportExportEverywhere, false)
};
// Use acorn-node's defaults for the rest.
if (opts.ecmaVersion != null) acornOpts.ecmaVersion = opts.ecmaVersion;
if (opts.sourceType != null) acornOpts.sourceType = opts.sourceType;
if (opts.allowHashBang != null) acornOpts.allowHashBang = opts.allowHashBang;
if (opts.allowReturnOutsideFunction != null) acornOpts.allowReturnOutsideFunction = opts.allowReturnOutsideFunction;
return acorn.parse(src, acornOpts);
}
function onwrite (row, enc, cb) {
if (mayContainSplitRequire(row.source)) {
var ast = acorn.parse(row.source)
row.transformable = transformAst(row.source, { ast: ast })
detectSplitRequireCalls(ast, function (node) {
if (node.parent.type === 'CallExpression' && node.parent.callee === node) {
processSplitRequire(row, node.parent)
}
}, function (node) {
// Mark the thing we imported as the runtime row.
var importPath = getStringValue(node.arguments[0])
runtimeId = row.deps[importPath]
if (rowsById[runtimeId]) {
runtimeRow = rowsById[runtimeId]
}
})
}
if (runtimeId && String(row.id) === String(runtimeId)) {
module.exports = function (src) {
// If src is a Buffer, esprima will just stringify it, so we beat them to
// the punch. This avoids the problem where we're using esprima's range
// indexes -- which are meant for a UTF-16 string -- in a buffer that
// contains UTF-8 encoded text.
if (typeof src !== 'string') {
src = String(src);
}
var ast = parse(src, { range: true });
ast.body = ast.body.filter(function(node) {
return node.type !== 'EmptyStatement';
});
if (ast.body.length !== 1) return;
if (ast.body[0].type !== 'ExpressionStatement') return;
if (ast.body[0].expression.type === 'UnaryExpression') {
var body = ast.body[0].expression.argument;
} else if (ast.body[0].expression.type === 'AssignmentExpression') {
var body = ast.body[0].expression.right;
} else {
var body = ast.body[0].expression;
}
if (body.type !== 'CallExpression') return;
if (state !== ST_INSIDE_CALL && token.type === acorn.tokTypes.dot) {
state = ST_MEMBER_EXPRESSION;
} else if (state === ST_NONE && token.type === acorn.tokTypes.name && mayBeRequire(token)) {
state = ST_SAW_NAME;
opener = token;
} else if (state === ST_SAW_NAME && token.type === acorn.tokTypes.parenL) {
state = ST_INSIDE_CALL;
args = [];
} else if (state === ST_INSIDE_CALL) {
if (token.type === acorn.tokTypes.parenR) { // End of fn() call
if (args.length === 1 && args[0].type === acorn.tokTypes.string) {
modules.strings.push(args[0].value);
} else if (args.length === 3 // A template string without any expressions
&& args[0].type === acorn.tokTypes.backQuote
&& args[1].type === acorn.tokTypes.template
&& args[2].type === acorn.tokTypes.backQuote) {
modules.strings.push(args[1].value);
} else if (args.length > 0) {
modules.expressions.push(src.slice(args[0].start, args[args.length - 1].end));
}
if (opts.nodes) {
// Cut `src` at the end of this call, so that parseExpressionAt doesn't consider the `.abc` in
// `require('xyz').abc`
var chunk = src.slice(0, token.end);
var node = acorn.parseExpressionAt(chunk, opener.start, opts.parse);
modules.nodes.push(node);
}
state = ST_NONE;
} else {
function (token) { return token.type === acorn.tokTypes.num || token.type === acorn.tokTypes.string; }, // 0
function (token) { return token.type === acorn.tokTypes.colon; }, // :
if (args.length === 1 && args[0].type === acorn.tokTypes.string) {
modules.strings.push(args[0].value);
} else if (args.length === 3 // A template string without any expressions
&& args[0].type === acorn.tokTypes.backQuote
&& args[1].type === acorn.tokTypes.template
&& args[2].type === acorn.tokTypes.backQuote) {
modules.strings.push(args[1].value);
} else if (args.length > 0) {
modules.expressions.push(src.slice(args[0].start, args[args.length - 1].end));
}
if (opts.nodes) {
// Cut `src` at the end of this call, so that parseExpressionAt doesn't consider the `.abc` in
// `require('xyz').abc`
var chunk = src.slice(0, token.end);
var node = acorn.parseExpressionAt(chunk, opener.start, opts.parse);
modules.nodes.push(node);
}
state = ST_NONE;
} else {
args.push(token);
}
} else if (REQUIRE_REDEF_PATTERN[0](token)) {
state = ST_REDEF_PATTERN;
redefIndex = 1;
} else {
state = ST_NONE;
}
}
return modules;
module.exports = function findFast(src, opts) {
if (!opts) opts = {};
if (typeof src !== 'string') src = String(src);
if (opts.word === undefined) opts.word = 'require';
var tokenizer = acorn.tokenizer(src, opts.parse);
var token;
var state = ST_NONE;
// Current index in the require redefinition pattern.
var redefIndex = 0;
// Block scope depth when require was redefined. This is used to match the
// correct } with the opening { after the redefining function parameter list.
var redefDepth = 0;
var opener;
var args = [];
var modules = { strings: [], expressions: [] };
if (opts.nodes) modules.nodes = [];
while ((token = tokenizer.getToken()) && token.type !== acorn.tokTypes.eof) {
if (state === ST_REDEFINED) {
function onend (cb) {
if (!mayContainSplitRequire(source)) {
cb()
return
}
if (this.listenerCount('dep') === 0) {
throw new Error('split-require requires browserify v16 or up')
}
var self = this
var ast = acorn.parse(source)
detectSplitRequireCalls(ast, function (node) {
if (node.parent.type === 'CallExpression') {
var arg = node.parent.arguments[0]
self.emit('dep', arg.value)
}
})
cb()
}
}
function visit(node, st, c) {
var hasRequire = wordRe.test(src.slice(node.start, node.end));
if (!hasRequire) return;
walk.base[node.type](node, st, c);
if (node.type !== 'CallExpression') return;
if (isRequire(node)) {
if (node.arguments.length) {
var arg = node.arguments[0];
if (arg.type === 'Literal') {
modules.strings.push(arg.value);
}
else if (arg.type === 'TemplateLiteral'
&& arg.quasis.length === 1
&& arg.expressions.length === 0) {
modules.strings.push(arg.quasis[0].value.raw);
}
else {
modules.expressions.push(src.slice(arg.start, arg.end));
}