Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function resolveScope( ast, node ) {
var visitors;
var scope;
visitors = {};
visitors[ node.type ] = onVisit;
scope = [];
walk( ast, visitors );
return scope;
/**
* Callback invoked upon encountering an AST node.
*
* @private
* @param {Node} n - AST node
* @param {Array} parents - array of parent AST nodes
*/
function onVisit( n, parents ) {
var locals;
var i;
var j;
if ( n === node ) {
// Note: the direction in which we traverse the list of parents does not matter, as we only care about identifier names, not where they were declared and to what value they are assigned. Meaning, we don't need to concern ourselves with whether a local scope redeclares a variable in a higher scope, as we are only concerned with a general list of identifier names available at the location of the provided AST node.
function walkForProtectedAssignment (ast, results) {
walk.ancestor(ast, {
'AssignmentExpression': function (node, parents) {
const { left } = node
// select for assignment to a property
if (left.type !== 'MemberExpression') return
const { property, computed } = left
// skip if property name is a variable
if (computed) return
if (property.type !== 'Identifier') return
// check for assignment to primordial
const memberPath = memberExpressionChainToPath(left)
const match = primordialPaths.some(
primordial => partialArrayMatch(primordial, memberPath)
)
if (match) {
results.push(node)
}
throw new TypeError( 'invalid argument. Must provide a program AST node.' );
}
globals = [];
// Resolve local scopes:
ast = resolveLocalScopes( ast );
// Define callbacks for relevant AST nodes:
visitors = {
'VariablePattern': Identifier,
'Identifier': Identifier,
'ThisExpression': ThisExpression
};
// Walk the AST to resolve globals:
walk( ast, visitors );
return globals;
/**
* Callback invoked upon encountering an identifier AST node.
*
* @private
* @param {Node} node - AST node
* @param {Array} parents - array of parent AST nodes
*/
function Identifier( node, parents ) {
var locals;
var name;
var i;
name = node.name;
if (parent.argument === leaf) {
parent.argument = getNewNode(leaf)
}
break
case 'Property':
if (parent.value === leaf) {
parent.shorthand = false
parent.value = getNewNode(leaf)
}
break
default:
// NOP
}
}
walk.ancestor(ast, types.reduce((target, type) => ({
...target,
[type]: typeCallback,
}), {}))
}
function checkConst(node, parents) {
switch (node.type) {
case "Identifier":
case "VariablePattern": {
identifier(node, parents);
break;
}
case "ArrayPattern":
case "ObjectPattern": {
ancestor(
node,
{
Identifier: identifier,
VariablePattern: identifier
},
walk
);
break;
}
}
function identifier(node, nodeParents) {
for (const parent of parents) {
if (hasLocal(parent, node.name)) {
return;
}
}
function ancestor (node, visitors, baseVisitor, state) {
return walk.ancestor(node, visitors, baseVisitor || base, state)
}
function checkConst(node, parents) {
switch (node.type) {
case "Identifier":
case "VariablePattern": {
identifier(node);
break;
}
case "ArrayPattern":
case "ObjectPattern": {
ancestor(
node,
{
Identifier: identifier,
VariablePattern: identifier
},
walk
);
break;
}
}
function identifier(node) {
const {name} = node;
if (!definesLocal(name, parents)) {
throw node;
}
}
function ancestor (node, visitors, baseVisitor, state) {
return walk.ancestor(node, visitors, baseVisitor || base, state)
}
function ancestor (node, visitors, baseVisitor, state) {
return walk.ancestor(node, visitors, baseVisitor || base, state)
}