/*
descendOn = true                     Enter scopes within scopes
descendOn = false/undefined/null     Do not enter scopes within scopes
descendOn = function                 Descend when function(node) is true
977814
function contains(ast, fn, descendOn) {
        if (!ast) 
            return null;
        if (fn && typeof fn === 'object') {
            var keys = Object.keys(fn);
            return contains(ast, function (node) {
                return keys.every(function (k) {
                    return node[k] == fn[k];
                });
            });
        }
        var n, found = {};
        if (Array.isArray(ast)) {
            for (var i = 0;i < ast.length; i++) 
                if (n = contains(ast[i], fn)) 
                return n;
            return null;
        }
        var subScopes = descendOn;
        if (typeof descendOn !== "function") {
            if (descendOn) {
                subScopes = function (n) {
                    return true;
                };
            } else {
                subScopes = function (n) {
                    return !examine(n).isScope;
                };
            }
        }
        try {
            treeWalk(ast, function (node, descend, path) {
                if (fn(node)) {
                    found.path = path;
                    throw found;
                }
                if (node === ast || subScopes(node)) 
                    descend();
            });
        } catch (ex) {
            if (ex === found) 
                return found.path;
            throw ex;
        }
        return null;
    }
367195
function usesScopeName(scopeNames, node) {
    function usesScope(root) {
        return usesScopeName(scopeNames, root)
    }
    if (_.isEmpty(scopeNames)) {
        return false
    }
    // rt-if="x"
    if (node.type === 'Identifier') {
        return _.includes(scopeNames, node.name)
    }
    // rt-if="e({key1: value1})"
    if (node.type === 'Property') {
        return usesScope(node.value)
    }
    // rt-if="e.x" or rt-if="e1[e2]"
    if (node.type === 'MemberExpression') {
        return node.computed ? usesScope(node.object) || usesScope(node.property) : usesScope(node.object)
    }
    // rt-if="!e"
    if (node.type === 'UnaryExpression') {
        return usesScope(node.argument)
    }
    // rt-if="e1 || e2" or rt-if="e1 | e2"
    if (node.type === 'LogicalExpression' || node.type === 'BinaryExpression') {
        return usesScope(node.left) || usesScope(node.right)
    }
    // rt-if="e1(e2, ... eN)"
    if (node.type === 'CallExpression') {
        return usesScope(node.callee) || _.some(node.arguments, usesScope)
    }
    // rt-if="f({e1: e2})"
    if (node.type === 'ObjectExpression') {
        return _.some(node.properties, usesScope)
    }
    // rt-if="e1[e2]"
    if (node.type === 'ArrayExpression') {
        return _.some(node.elements, usesScope)
    }
    return false
}
738672
function traverse(ast) {
    var visitors = flatten(slice.call(arguments, 1));

    estraverse.traverse(ast, {
        enter: function(node) {
            var type = node.type;
            var methodName = type + 'Enter';
            visitorsCall('enter', this, arguments);
            visitorsCall(methodName, this, arguments);
        },
        leave: function(node) {
            var type = node.type;
            var methodName = type + 'Leave';
            visitorsCall('leave', this, arguments);
            visitorsCall(methodName, this, arguments);
        }
    });


    function visitorsCall(methodName, context, args) {
        var callArgs = slice.call(args);
        var callBreak;
        var visitorContext = Object.assign(
            Object.create(context),
            {
                skip: function() {
                    callBreak = true;
                    context.skip();
                },
                break: function() {
                    callBreak = true;
                    context.break();
                }
            }
        );
        visitors.some(function(visitor) {
            var method = visitor[methodName];
            if (method) {
                method.apply(visitorContext, callArgs);
            }
            return callBreak;
        });
    }
}
1364653
function first(a, fn, scope) {
    for (var i = 0, l = a.length; i < l; i++) {
      if (fn.call(scope || null, a[i]))
        return a[i];
    }
    return;
  }
749404
function () {
      let scope = context.getScope();
      while (scope && scope.type !== 'class') {
        scope = scope.upper;
      }
      const node = scope && scope.block;
      if (!node || !utils.isES6Component(node)) {
        return null;
      }
      return node;
    }
653823
function isUsedFromOutsideOf(scopeNode) {

    /**
     * Checks whether a given reference is inside of the specified scope or not.
     *
     * @param {eslint-scope.Reference} reference - A reference to check.
     * @returns {boolean} `true` if the reference is inside of the specified
     *      scope.
     */
    function isOutsideOfScope(reference) {
        const scope = scopeNode.range;
        const id = reference.identifier.range;

        return id[0] < scope[0] || id[1] > scope[1];
    }

    return function(variable) {
        return variable.references.some(isOutsideOfScope);
    };
}
578744
function(fn, opts) {
			var children,
				idx,
				parent,
				includeHidden = !!opts.includeHidden,
				node = opts.start || this.rootNode.children[0];

			while (true) {
				parent = node.parent;
				children = parent.children;

				if (children[0] === node) {
					// If this is already the first sibling, goto parent
					node = parent;
					children = parent.children;
				} else {
					// Otherwise, goto prev. sibling
					idx = children.indexOf(node);
					node = children[idx - 1];
					// If the prev. sibling has children, follow down to last descendant
					while (
						(includeHidden || node.expanded) &&
						node.children &&
						node.children.length
					) {
						children = node.children;
						parent = node;
						node = children[children.length - 1];
					}
				}
				// Skip invisible
				if (!includeHidden && !$(node.span).is(":visible")) {
					continue;
				}
				if (fn(node) === false) {
					return false;
				}
			}
		}
219774
function traverseEnterLeave(from, to, fn, argFrom, argTo) {
  var common = from && to ? getLowestCommonAncestor(from, to) : null;
  var pathFrom = [];
  while (from && from !== common) {
    pathFrom.push(from);
    from = getParent(from);
  }
  var pathTo = [];
  while (to && to !== common) {
    pathTo.push(to);
    to = getParent(to);
  }
  var i;
  for (i = 0; i < pathFrom.length; i++) {
    fn(pathFrom[i], 'bubbled', argFrom);
  }
  for (i = pathTo.length; i-- > 0;) {
    fn(pathTo[i], 'captured', argTo);
  }
}
1073818
private void traverseAndRemoveUnusedReferences(Node root) {
    // Create scope from parent of root node, which also has externs as a child, so we'll
    // have extern definitions in scope.
    Scope scope = scopeCreator.createScope(root.getParent(), null);
    if (!scope.hasSlot(NodeUtil.JSC_PROPERTY_NAME_FN)) {
      // TODO(b/70730762): Passes that add references to this should ensure it is declared.
      // NOTE: null input makes this an extern var.
      scope.declare(
          NodeUtil.JSC_PROPERTY_NAME_FN, /* no declaration node */ null, /* no input */ null);
    }
    worklist.add(new Continuation(root, scope));
    while (!worklist.isEmpty()) {
      Continuation continuation = worklist.remove();
      continuation.apply();
    }

    removeUnreferencedVarsAndPolyfills();
    removeIndependentlyRemovableProperties();
    for (Scope fparamScope : allFunctionParamScopes) {
      removeUnreferencedFunctionArgs(fparamScope);
    }
  }
960128
function traverseTopDown(fn) {
    var result, i;
    result = fn.call(this);
    if(result)
        return result;
    if (this instanceof tree.ConsNode || this instanceof tree.ListNode) {
        for (i = 0; i < this.length; i++) {
            traverseTopDown.call(this[i], fn);
        }
    }
    return this;
}
1301439
function traverse(object, visitor) {
        var child;

        if (!object) {
            return;
        }

        if (visitor.call(null, object) === false) {
            return false;
        }
        for (var i = 0, keys = Object.keys(object); i < keys.length; i++) {
            child = object[keys[i]];
            if (typeof child === 'object' && child !== null) {
                if (traverse(child, visitor) === false) {
                    return false;
                }
            }
        }
    }
1233097
private boolean inLoop(Node n) {
    Node enclosingNode = NodeUtil.getEnclosingNode(n, isLoopOrFunction);
    return enclosingNode != null && !enclosingNode.isFunction();
  }
1243942
function (node, scope) {
      var finder = infer.typeFinder[node.type];
      return finder ? finder(node, scope) : infer.ANull;
    }
784435
@Nullable
    private ScopeBlock findPreviousSiblingScopeBlock(ScopeBlock sb) {
        ScopeBlock parent = sb.getParent();
        if (parent == null) {
            return null;
        }

        List<ScopeBlock> children = parent.getChildren();
        if (children == null) {
            return null;
        }

        ScopeBlock lastSibling = null;
        for (ScopeBlock sibling : children) {
            if (sibling.equals(sb)) {
                return lastSibling;
            }
            lastSibling = sibling;
        }

        return null;
    }
1311530
function Scope(parent) {
        this.names = {};        // names defined in this scope
        this.mangled = {};      // mangled names (orig.name => mangled)
        this.rev_mangled = {};  // reverse lookup (mangled => orig.name)
        this.cname = -1;        // current mangled name
        this.refs = {};         // names referenced from this scope
        this.uses_with = false; // will become TRUE if eval() is detected in this or any subscopes
        this.uses_eval = false; // will become TRUE if with() is detected in this or any subscopes
        this.parent = parent;   // parent scope
        this.children = [];     // sub-scopes
        if (parent) {
                this.level = parent.level + 1;
                parent.children.push(this);
        } else {
                this.level = 0;
        }
}
1037507
function Scope(data, affix, parent) {
  if (data !== undefined) {
    this.data = data;
  } else {
    this.data = {};
  }
  if (parent) {
    this.parent = parent;
    this.root = parent.root;
  } else {
    this.parent = undefined;
    this.root = this;
  }
  this.affix = affix || {};
  this.ready = false;
}
564495
function nodeIsUnscopedBinding(item: Node): boolean {
  const value = getValue(item);
  return value && value.unscoped;
}