6674943146dd8cb678f52999b61ef6c34db70672.svn-base 1.84 KB
var path    =  require('path')
var fs      =  require('fs')
var redeyed =  require('..')
var vm      =  require('vm')

var samplePath =  path.join(__dirname, 'sources', 'log.js')
var origCode   =  fs.readFileSync(samplePath, 'utf-8')
var kinds = [ 'silly', 'info', 'warn', 'error' ]

function replaceConsole(s, info) {
  var code        =  info.code
  var idx         =  info.tokenIndex
  var tokens      =  info.tokens
  var next        =  tokens[idx + 1].value
  var kind        =  tokens[idx + 2].value
  var openParen   =  tokens[idx + 3].value
  var firstArgTkn =  tokens[idx + 4]
  var argIdx      =  idx + 3
  var open
  var tkn

  if (kind === 'log') kind = 'silly'

  // not a console.xxx(...) statement? -> just return original
  if (next !== '.' || !~kinds.indexOf(kind) || openParen !== '(') return s

  // skip past arguments to console.xxx all args from ( to )
  open = 1
  while (open) {
    tkn = tokens[++argIdx]

    // count open parens vs. closed ones to handle things like console.log(new Error('..'));
    if (tkn.value === '(') open++
    if (tkn.value === ')') open--
  }

  // tkn now is the last closing paren
  var argsIncludingClosingParen =  code.slice(firstArgTkn.range[0], tkn.range[1])
  var result                    =  'log.' + kind + '("main-logger", ' + argsIncludingClosingParen

  // tell redeyed to skip the entire console.xxx(..) statement since we are replacing it all
  return { replacement: result, skipPastToken: tkn }
}

function transformAndRun() {
  var config = {
        Identifier: { console: replaceConsole }
      }
  var code        =  redeyed(origCode, config).code
  var context     =  vm.createContext({ require: require })

  console.log('Original code:\n', origCode)
  console.log('\nlog calls replaced:\n', code)
  console.log('\nLets run it:')
  vm.runInContext(code, context, 'transformed-log.vm')
}

transformAndRun()