lib/detect-globals.js
function setupContext(node) {
  if (node.type === 'Program') {
    node.context = GLOBAL_CONTEXT;
    return;
  }

  // default context is the parent context
  node.context = node.parent.context;

  // IIFE (function(win){ win.x = 'x' }(window))
  if ( isIIFE(node) ) {
    var args = node.arguments;
    var params = node.callee.params;
    if (args.length && params.length) {
      params.forEach(function(param, i){
        var arg = args[i] || {};
        var init = arg.type === 'ThisExpression'? node.context : arg.name;
        addVarToScope(node, {
          name: param.name,
          init: init
        });
      });
    }
    node.context = node.parent.context;
    return;
  }

  // function.call and function.apply change the context
  if (node.type === 'CallExpression' &&
      node.callee.type === 'MemberExpression' &&
      (node.callee.property.name === 'call' || node.callee.property.name === 'apply')) {

    var arg = node.arguments[0];
    var ctx = (!arg || arg.type === 'ThisExpression' ||
      (arg.type === 'Literal' && arg.value == null))? GLOBAL_CONTEXT : CUSTOM_CONTEXT;

    addVarToScope(node, {
      name: 'this',
      init: ctx,
      pointer: ctx
    });

    node.context = ctx;
    return;
  }

  if ((node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration') && !isIIFE(node.parent)) {
    // params are "free variables"
    node.params.forEach(function(param){
      addVarToScope(node, {
        name: param.name,
        init: undefined
      });
    });

    // by default we assume that all properties of object use "this" to referece
    // itself even tho this might not be true depending on how the method is
    // called
    if (node.parent.type === 'Property' ||
        (node.parent.type === 'AssignmentExpression' &&
         node.parent.left.type === 'MemberExpression')) {
      node.context = CUSTOM_CONTEXT;
      return;
    }
  }

}
function setupContext(node) {
  if (node.type === 'Program') {
    node.context = GLOBAL_CONTEXT;
    return;
  }

  // default context is the parent context
  node.context = node.parent.context;

  // IIFE (function(win){ win.x = 'x' }(window))
  if ( isIIFE(node) ) {
    var args = node.arguments;
    var params = node.callee.params;
    if (args.length && params.length) {
      params.forEach(function(param, i){
        var arg = args[i] || {};
        var init = arg.type === 'ThisExpression'? node.context : arg.name;
        addVarToScope(node, {
          name: param.name,
          init: init
        });
      });
    }
    node.context = node.parent.context;
    return;
  }

  // function.call and function.apply change the context
  if (node.type === 'CallExpression' &&
      node.callee.type === 'MemberExpression' &&
      (node.callee.property.name === 'call' || node.callee.property.name === 'apply')) {

    var arg = node.arguments[0];
    var ctx = (!arg || arg.type === 'ThisExpression' ||
      (arg.type === 'Literal' && arg.value == null))? GLOBAL_CONTEXT : CUSTOM_CONTEXT;

    addVarToScope(node, {
      name: 'this',
      init: ctx,
      pointer: ctx
    });

    node.context = ctx;
    return;
  }

  if ((node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration') && !isIIFE(node.parent)) {
    // params are "free variables"
    node.params.forEach(function(param){
      addVarToScope(node, {
        name: param.name,
        init: undefined
      });
    });

    // by default we assume that all properties of object use "this" to referece
    // itself even tho this might not be true depending on how the method is
    // called
    if (node.parent.type === 'Property' ||
        (node.parent.type === 'AssignmentExpression' &&
         node.parent.left.type === 'MemberExpression')) {
      node.context = CUSTOM_CONTEXT;
      return;
    }
  }

}
function setupContext ( node ) { if ( node . type === 'Program' ) { node . context = GLOBAL_CONTEXT ; return ; } // default context is the parent context node . context = node . parent . context ; // IIFE (function(win){ win.x = 'x' }(window)) if ( isIIFE ( node ) ) { var args = node . arguments ; var params = node . callee . params ; if ( args . length && params . length ) { params . forEach ( function ( param , i ) { var arg = args [ i ] || { } ; var init = arg . type === 'ThisExpression' ? node . context : arg . name ; addVarToScope ( node , { name : param . name , init : init } ) ; } ) ; } node . context = node . parent . context ; return ; } // function.call and function.apply change the context if ( node . type === 'CallExpression' && node . callee . type === 'MemberExpression' && ( node . callee . property . name === 'call' || node . callee . property . name === 'apply' ) ) { var arg = node . arguments [ 0 ] ; var ctx = ( ! arg || arg . type === 'ThisExpression' || ( arg . type === 'Literal' && arg . value == null ) ) ? GLOBAL_CONTEXT : CUSTOM_CONTEXT ; addVarToScope ( node , { name : 'this' , init : ctx , pointer : ctx } ) ; node . context = ctx ; return ; } if ( ( node . type === 'FunctionExpression' || node . type === 'FunctionDeclaration' ) && ! isIIFE ( node . parent ) ) { // params are "free variables" node . params . forEach ( function ( param ) { addVarToScope ( node , { name : param . name , init : undefined } ) ; } ) ; // by default we assume that all properties of object use "this" to referece // itself even tho this might not be true depending on how the method is // called if ( node . parent . type === 'Property' || ( node . parent . type === 'AssignmentExpression' && node . parent . left . type === 'MemberExpression' ) ) { node . context = CUSTOM_CONTEXT ; return ; } } }
gets reference to the "this" value
gets reference to the this value