import {analyze} from 'escope';
import {isFunction} from './utils/functionType';
const emptyFn = () => {}; // eslint-disable-line no-empty-function

/**
 * A helper for traversing with scope info from escope.
 *
 * Usage:
 *
 *     traverser.traverse(ast, withScope(ast, {
 *       enter(node, parent, scope) {
 *         // do something with node and scope
 *       }
 *     }))
 *
 * @param {Object} ast The AST root node also passed to traverser.
 * @param {Object} cfg Object with enter/leave function as expected by traverser.
 * @return {Object} Object with enter/leave functions to be passed to traverser.
 */
export default function withScope(ast, {enter = emptyFn, leave = emptyFn}) {
  const scopeManager = analyze(ast, {ecmaVersion: 6});
  let currentScope = scopeManager.acquire(ast);

  return {
    enter(node, parent) {
      if (isFunction(node)) {
        currentScope = scopeManager.acquire(node);
      }
      return enter.call(this, node, parent, currentScope);
    },
    leave(node, parent) {
      if (isFunction(node)) {
        currentScope = scopeManager.upper;
      }
      return leave.call(this, node, parent, currentScope);
    }
  };
}

import {analyze} from 'escope';
import {isFunction} from './utils/functionType';
const emptyFn = () => {}; // eslint-disable-line no-empty-function

/**
 * A helper for traversing with scope info from escope.
 *
 * Usage:
 *
 *     traverser.traverse(ast, withScope(ast, {
 *       enter(node, parent, scope) {
 *         // do something with node and scope
 *       }
 *     }))
 *
 * @param {Object} ast The AST root node also passed to traverser.
 * @param {Object} cfg Object with enter/leave function as expected by traverser.
 * @return {Object} Object with enter/leave functions to be passed to traverser.
 */
export default function withScope(ast, {enter = emptyFn, leave = emptyFn}) {
  const scopeManager = analyze(ast, {ecmaVersion: 6});
  let currentScope = scopeManager.acquire(ast);

  return {
    enter(node, parent) {
      if (isFunction(node)) {
        currentScope = scopeManager.acquire(node);
      }
      return enter.call(this, node, parent, currentScope);
    },
    leave(node, parent) {
      if (isFunction(node)) {
        currentScope = currentScope.upper;
      }
      return leave.call(this, node, parent, currentScope);
    }
  };
}

Use the correct upper scope
Use the correct upper scope

I'm not sure what bugs this is causing, but it definitely looks broken. There is no such thing as `scopeManager.upper`. Following the [docs](https://github.com/estools/escope/blob/aa35861faa76a09f01203dee3497a939d70b463c/README.md#example), we should use `currentScope.upper`.