Example #1
0
function generateMap(mappings, sourceRoot, mapFileBaseName, generatedLineOffset) {
  var SourceMapGenerator = require('source-map').SourceMapGenerator;

  var generator = new SourceMapGenerator({ file: mapFileBaseName });
  var seenFiles = Object.create(null);

  for (var generatedLineNumber in mappings) {
    var generatedLineNumber = parseInt(generatedLineNumber, 10);
    var mapping = mappings[generatedLineNumber];
    var originalFileName = mapping.originalFileName;
    generator.addMapping({
      generated: { line: generatedLineNumber + generatedLineOffset, column: 0 },
      original: { line: mapping.originalLineNumber, column: 0 },
      source: originalFileName
    });

    // we could call setSourceContent repeatedly, but readFileSync is slow, so
    // avoid doing it unnecessarily
    if (!(originalFileName in seenFiles)) {
      seenFiles[originalFileName] = true;
      var rootedPath = originalFileName[0] === path.sep ?
          originalFileName : path.join(sourceRoot, originalFileName);
      try {
        generator.setSourceContent(originalFileName, fs.readFileSync(rootedPath, 'utf-8'));
      } catch (e) {
        console.warn("sourcemapper: Unable to find original file for " + originalFileName +
          " at " + rootedPath);
      }
    }
  }

  fs.writeFileSync(mapFileBaseName + '.map', generator.toString());
}
function mergeMap(oldMap, newMap) {
  console.log(oldMap);
  console.log(newMap);
  var oldMapConsumer = new SM.SourceMapConsumer(oldMap)
  var newMapConsumer = new SM.SourceMapConsumer(newMap)
  var mergedMapGenerator = new SM.SourceMapGenerator()
  console.log(SM.SourceMapGenerator.fromSourceMap(newMapConsumer)._mappings.toArray())
  newMapConsumer.eachMapping((m, idx) => {
    var oldOrigPos = oldMapConsumer.originalPositionFor({line: m.originalLine, column: m.originalColumn})
    console.log(idx, m)
    console.log(idx, oldOrigPos);
    mergedMapGenerator.addMapping({
      generated: {
        line: m.generatedLine,
        column: m.generatedColumn
      },
      original: {
        line: oldOrigPos.line,
        column: oldOrigPos.column
      },
      source: m.source,
      name: m.name
    })
  })
  mergedMapGenerator.setSourceContent('multi-transform-t-dummy.js', gen2MapFromComment.sourcesContent[0])
  return JSON.parse(mergedMapGenerator.toString())
}
Example #3
0
    _.each(results, function (result) {
      var filename = result.filename;
      code += result.code + "\n";

      if (result.map) {
        var consumer = new sourceMap.SourceMapConsumer(result.map);

        var sourceFilename = filename;
        if (commander.outFile) {
          sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
        }
        sourceFilename = slash(sourceFilename);

        map._sources.add(sourceFilename);
        map.setSourceContent(sourceFilename, result.actual);

        consumer.eachMapping(function (mapping) {
          map._mappings.add({
            generatedLine: mapping.generatedLine + offset,
            generatedColumn: mapping.generatedColumn,
            originalLine: mapping.originalLine,
            originalColumn: mapping.originalColumn,
            source: sourceFilename
          });
        });

        offset = code.split("\n").length;
      }
    });
Example #4
0
function forSource(data, sourcePath) {
    if (! data) {
        throw new Error('Missing data in SourceMap.forSource');
    }

    if (! sourcePath) {
        throw new Error('Missing sourcePath in SourceMap.forSource');
    }

    var generator = new SourceMapGenerator({
        // FIXME: or just filename?
        file: path.basename(sourcePath)
    });

    generator.setSourceContent(sourcePath, data);

    data.split('\n').forEach(function(l, i) {
        generator.addMapping({
            generated: { line: i + 1, column: null },
            original:  { line: i + 1, column: null },
            source: sourcePath
        });
    });

    return fromMapObject(generator.toJSON());
}
function genSourceMap(modules) {
  var sourceMapGen = new SourceMapGenerator({file: 'bundle.js', version: 3});
  var bundleLineNo = 0;
  for (var i = 0; i < modules.length; i++) {
    var module = modules[i];
    var transformedCode = module.code;
    var sourcePath = module.sourcePath;
    var sourceCode = module.sourceCode;
    var transformedLineCount = 0;
    var lastCharNewLine = false;
    for (var t = 0; t < transformedCode.length; t++) {
      if (t === 0 || lastCharNewLine) {
        sourceMapGen.addMapping({
          generated: {line: bundleLineNo + 1, column: 0},
          original: {line: transformedLineCount + 1, column: 0},
          source: sourcePath
        });
      }
      lastCharNewLine = transformedCode[t] === '\n';
      if (lastCharNewLine) {
        transformedLineCount++;
        bundleLineNo++;
      }
    }
    bundleLineNo++;
    sourceMapGen.setSourceContent(
      sourcePath,
      sourceCode
    );
  }
  return sourceMapGen.toJSON();
}
Example #6
0
Context.prototype.createSourceMapObject = function (obj) {
  var map;

  if (obj.map) {
    map = JSON.parse(obj.map);
    map.sourceRoot = '';
    return map;
  }

  var name = path.basename(obj.file);
  var smg = new sourcemap.SourceMapGenerator({ file: name });

  obj.data.split('\n').forEach(function (line, idx) {
    smg.addMapping({
      source: name,
      original: { line: idx + 1, column: 0 },
      generated: { line: idx + 1, column: 0 }
    });
  });
  smg.setSourceContent(name, obj.data);

  map = smg.toJSON();
  map.sourceRoot = '';

  return map;
};
Example #7
0
 secret.mappings.forEach(function(mapping) {
   var sourceCursor = mapping.sourceLines.skipSpaces(mapping.sourceLoc.start) || mapping.sourceLines.lastPos();
   var targetCursor = targetLines.skipSpaces(mapping.targetLoc.start) || targetLines.lastPos();
   while (comparePos(sourceCursor, mapping.sourceLoc.end) < 0 && comparePos(targetCursor, mapping.targetLoc.end) < 0) {
     var sourceChar = mapping.sourceLines.charAt(sourceCursor);
     var targetChar = targetLines.charAt(targetCursor);
     assert.strictEqual(sourceChar, targetChar);
     var sourceName = mapping.sourceLines.name;
     smg.addMapping({
       source: sourceName,
       original: {
         line: sourceCursor.line,
         column: sourceCursor.column
       },
       generated: {
         line: targetCursor.line,
         column: targetCursor.column
       }
     });
     if (!hasOwn.call(sourcesToContents, sourceName)) {
       var sourceContent = mapping.sourceLines.toString();
       smg.setSourceContent(sourceName, sourceContent);
       sourcesToContents[sourceName] = sourceContent;
     }
     targetLines.nextPos(targetCursor, true);
     mapping.sourceLines.nextPos(sourceCursor, true);
   }
 });
Example #8
0
 function patchSourcemap(patches, rsm, smc) {
     var smg = new sm.SourceMapGenerator({
         file: rsm.file,
         sourceRoot: rsm.sourceRoot
     });
     patches = patches.reverse();
     var currentLine = -1;
     var currentLineDiff = 0;
     var source = null;
     smc.eachMapping(function (m) {
         var patch = patches[patches.length - 1];
         var original = { line: m.originalLine, column: m.originalColumn };
         var generated = { line: m.generatedLine, column: m.generatedColumn };
         if (currentLine !== generated.line) {
             currentLineDiff = 0;
         }
         currentLine = generated.line;
         generated.column += currentLineDiff;
         if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
             var originalLength = patch.span.end.character - patch.span.start.character;
             var modifiedLength = patch.content.length;
             var lengthDiff = modifiedLength - originalLength;
             currentLineDiff += lengthDiff;
             generated.column += lengthDiff;
             patches.pop();
         }
         source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
         source = source.replace(/\\/g, '/');
         smg.addMapping({ source: source, name: m.name, original: original, generated: generated });
     }, null, sm.SourceMapConsumer.GENERATED_ORDER);
     if (source) {
         smg.setSourceContent(source, smc.sourceContentFor(source));
     }
     return JSON.parse(smg.toString());
 }
Example #9
0
function generateCss(sourcePath, fileContent) {
  var generator = new SourceMapGenerator({ file: sourcePath });
  var ast = css.parse(fileContent, { silent: true });

  function registerTokens(ast) {
    if (ast.position) {
      generator.addMapping({
        original: ast.position.start,
        generated: ast.position.start,
        source: sourcePath,
      });
    }

    for (var key in ast) {
      if (key === 'position' || !ast[key]) {
        break;
      }
      if (Object.prototype.toString.call(ast[key]) === '[object Object]') {
        registerTokens(ast[key]);
      } else if (Array.isArray(ast[key])) {
        ast[key].forEach(registerTokens);
      }
    }
  }
  registerTokens(ast);
  generator.setSourceContent(sourcePath, fileContent);

  return generator.toJSON();
}
var makeSourceMapGenerator = function makeSourceMapGenerator(file) {
  var filename = file.sourceFileName;
  var generator = new _sourceMap.SourceMapGenerator({
    file: filename,
    sourceRoot: file.sourceRoot
  });
  generator.setSourceContent(filename, file.code);
  return generator;
};
Example #11
0
function createSourceMap({ source, mappings, code }) {
  const generator = new SourceMapGenerator({ file: source.url });
  mappings.forEach(mapping => generator.addMapping(mapping));
  generator.setSourceContent(source.url, code);

  let consumer = SourceMapConsumer.fromSourceMap(generator);
  _setConsumer(source, consumer);
  return generator.toJSON();
}
Example #12
0
function makeSourceMapGenerator(file) {
  var generatorOpts = getGeneratorOpts(file);
  var filename = generatorOpts.sourceFileName;
  var generator = new SourceMapGenerator({
    file: filename,
    sourceRoot: generatorOpts.sourceRoot
  });
  generator.setSourceContent(filename, file.code);
  return generator;
}
Example #13
0
export function makeSourceMapGenerator(file) {
  const filename = file.opts.sourceFileName
  const generator = new SourceMapGenerator({
    file: filename,
    sourceRoot: file.opts.sourceRoot
  })

  generator.setSourceContent(filename, file.code)
  return generator
}
Example #14
0
function withSourceMap(src, compiled, name, options) {

  //return compiled;

  var compiledLines = compiled.split('\n');
  var generator = new SourceMapGenerator({file: name + '.js'});

  var runTemplateSuffix = '';

  if (options.runTemplate) {

    options.locals = options.locals || {};
    if (options.urlPrefix) {
      options.locals.staticUrl = _staticUrl(options.filename, options.urlPrefix, options.__dirname);
    }

    runTemplateSuffix = "({staticUrl:"+options.locals.staticUrl+"})";
  }

  compiledLines.forEach(function(l, lineno) {
    var m = l.match(/^jade(_|\.)debug\.unshift\(\{ lineno: ([0-9]+)/);
    if (m) {
      var originalLine = Number(m[2]);
      var generatedLine = lineno + 2;

      if (originalLine > 0) {
        generator.addMapping({
          generated: {
            line: generatedLine,
            column: 0
          },
          source: name,
          original: {
            line: originalLine,
            column: 0
          }
        });
      }
    }

    var debugRe = /jade(_|\.)debug\.(shift|unshift)\([^)]*\);?/;
    var match;
    while(match = l.match(debugRe)) {
      l = replaceMatchWith(match, '');
    }
    compiledLines[lineno] =l;
  });
  generator.setSourceContent(name, src);

  var map = convert.fromJSON(generator.toString());
  compiledLines.push(SUFFIX);
  compiledLines.push(runTemplateSuffix);
  compiledLines.push(map.toComment());
  return compiledLines.join('\n');
}
Example #15
0
function applySourceMap(
  generatedId: string,
  url: string,
  code: string,
  mappings: Object
) {
  const generator = new SourceMapGenerator({ file: url });
  mappings.forEach(mapping => generator.addMapping(mapping));
  generator.setSourceContent(url, code);

  const map = createConsumer(generator.toJSON());
  setSourceMap(generatedId, Promise.resolve(map));
}
Example #16
0
function withSourceMap(src, compiled, name) {

  var compiledLines = compiled.split('\n');
  var generator = new SourceMapGenerator({file: name + '.js'});

  compiledLines.forEach(function(l, lineno) {
    var m = l.match(/^jade(_|\.)debug\.unshift\(new jade\.DebugItem\( ([0-9]+)/);
    // Check for older jade debug line format
    if (!m) m = l.match(/^(pug|jade)(_|\.)debug\.unshift\(\{ lineno: ([0-9]+)/);
    if (m) {
      var originalLine = Number(m[2]);
      var generatedLine = lineno + 2;

      if (originalLine > 0) {
        generator.addMapping({
          generated: {
            line: generatedLine,
            column: 0
          },
          source: name,
          original: {
            line: originalLine,
            column: 0
          }
        });
      }
    }

    var debugRe = /(pug|jade)(_|\.)debug\.(shift|unshift)\([^;]*\);/;
    var match;
    while(match = l.match(debugRe)) {
      l = replaceMatchWith(match, '');
    }
    compiledLines[lineno] =l;
  });

  // Remove jade debug lines at beginning and end of compiled version
  if (/var jade_debug = /.test(compiledLines[1])) compiledLines[1] = '';
  if (/try \{/.test(compiledLines[2])) compiledLines[2] = '';
  var l = compiledLines.length;
  if (/\} catch \(err\) \{/.test(compiledLines[l-4])) {
    compiledLines[l-2] = compiledLines[l-3] = compiledLines[l-4] = '';
  }

  generator.setSourceContent(name, src);

  var map = convert.fromJSON(generator.toString());
  compiledLines.push(map.toComment());
  return compiledLines.join('\n');
}
Example #17
0
 _initSourceMap(opts, code) {
   if (opts.sourceMaps) {
     if (!opts.sourceFileName) {
       throw new Error("sourceFileName must be set when generating source maps")
     }
     this.map = new sourceMap.SourceMapGenerator({
       file: opts.sourceMapTarget,
       sourceRoot: opts.sourceRoot
     });
     this.map.setSourceContent(opts.sourceFileName, code);
   } else {
     this.map = null;
   }
 }
Example #18
0
export default function generate(pundle: Pundle, contents: Array<File>, requires: Array<string>, givenConfig: Object) {
  let lines = 0
  const config = Helpers.fillConfig(givenConfig)

  const output = []
  const sourceMap = new SourceMapGenerator({
    skipValidation: true,
  })

  if (config.wrapper === 'normal') {
    output.push(WrapperNormal)
    lines += Helpers.getLinesCount(WrapperNormal)
  } else if (config.wrapper === 'hmr') {
    output.push(WrapperHMR)
    lines += Helpers.getLinesCount(WrapperHMR)
  } else {
    lines = 1
  }
  for (const file of (contents: Array<File>)) {
    const fileContents = file.contents.trim()
    const entry = `__sb_pundle_register('${pundle.getUniquePathID(file.filePath)}', function(module, exports) {\n${fileContents}\n});`
    output.push(entry)

    if (!config.sourceMap) {
      continue
    }

    const entryPath = file.filePath.replace('$root', `$${config.projectName}`)
    const entryMap = new SourceMapConsumer(file.sourceMap)
    for (const mapping of entryMap._generatedMappings) {
      sourceMap.addMapping({
        source: entryPath,
        original: { line: mapping.originalLine, column: mapping.originalColumn },
        generated: { line: lines + mapping.generatedLine, column: mapping.generatedColumn },
      })
    }
    lines += Helpers.getLinesCount(fileContents)
    lines ++
    sourceMap.setSourceContent(entryPath, file.source)
  }
  for (const entry of (requires: Array<string>)) {
    output.push(`__require('${pundle.getUniquePathID(entry)}')`)
  }

  return {
    contents: output.join(''),
    sourceMap: config.sourceMap ? sourceMap.toJSON() : null,
  }
}
Example #19
0
  constructor(position, opts, code) {
    this.position = position;
    this.opts     = opts;

    if (opts.sourceMaps) {
      this.map = new sourceMap.SourceMapGenerator({
        file: opts.sourceMapName,
        sourceRoot: opts.sourceRoot
      });

      this.map.setSourceContent(opts.sourceFileName, code);
    } else {
      this.map = null;
    }
  }
Example #20
0
function makeIdentitySourceMap(content, resourcePath) {
  var map = new sm.SourceMapGenerator();
  map.setSourceContent(resourcePath, content);
  content.split('\n').map(function(line, index) {
    map.addMapping({
      source: resourcePath,
      original: {
        line: index+1,
        column: 0
      },
      generated: {
        line: index+1,
        column: 0
      }
    });
  });
  return map.toJSON();
}
Example #21
0
/**
 * Create source map from 'content'
 * @param {String} content
 * @param {String} [url]
 * @returns {SourceMapGenerator}
 */
function create(content, url) {
  url = url || '<source>';
  const map = new SourceMapGenerator({ file: url });
  const lines = content.split('\n');

  for (let l = 1, n = lines.length; l <= n; l++) {
    // Skip empty
    if (lines[l - 1]) {
      map.addMapping({
        source: url,
        original: { line: l, column: 0 },
        generated: { line: l, column: 0 }
      });
    }
  }

  map.setSourceContent(url, content);
  return map;
}
Example #22
0
  function end() {
    var source = buf.join('')
      , transformed = streamline.transform(source, transformOptions)

    // https://github.com/Sage/streamlinejs/issues/251
    if (typeof transformed === 'string') {
      stream.queue(transformed)
      stream.queue(null)
      return
    }

    var compiled = transformed.toStringWithSourceMap({ file: file })
      , consumer = new SourceMapConsumer(compiled.map.toString())
      , generator = new SourceMapGenerator({ file: file })

    generator.setSourceContent(file, source)

    consumer.eachMapping(function (mapping) {
      mapping.source = path.normalize(mapping.source || '')

      // Ignore mappings that are not from our source file
      if (!mapping.source || file !== mapping.source) return

      generator.addMapping(
        { original:
          { column: mapping.originalColumn
          , line: mapping.originalLine
          }
        , generated:
          { column: mapping.generatedColumn
          , line: mapping.generatedLine
          }
        , source: file
        , name: mapping.name
        }
      )
    })

    stream.queue(compiled.code)
    stream.queue('\n//@ sourceMappingURL=data:application/json;base64,')
    stream.queue(new Buffer(generator.toString()).toString('base64'))
    stream.queue(null)
  }
Example #23
0
function generateSourceMap (filename, source, generated, sourceRoot) {
  var map = new SourceMapGenerator({ sourceRoot })
  map.setSourceContent(filename, source)
  generated.split(splitRE).forEach((line, index) => {
    if (!emptyRE.test(line)) {
      map.addMapping({
        source: filename,
        original: {
          line: index + 1,
          column: 0
        },
        generated: {
          line: index + 1,
          column: 0
        }
      })
    }
  })
  return map.toJSON()
}
Example #24
0
export function generateMap (loader, source, iterator) {
  const filePath = loader.resourcePath

  const fileNameWithHash = getFileNameWithHash(filePath)
  const sourceRoot = path.resolve('.')

  const map = new SourceMapGenerator({
    sourceRoot,
    skipValidation: true
  })
  map.setSourceContent(fileNameWithHash, source)

  for (const { original, generated } of iterator) {
    map.addMapping({
      source: fileNameWithHash,
      original,
      generated
    })
  }

  return map
}
Example #25
0
  constructor(position, opts, code) {
    this.position = position;
    this.opts     = opts;
    this.last     = {generated: {}, original: {}};

    if (opts.sourceMaps) {
      this.map = new sourceMap.SourceMapGenerator({
        file: opts.sourceMapTarget,
        sourceRoot: opts.sourceRoot
      });

      if (typeof code === "string") {
        this.map.setSourceContent(opts.sourceFileName, code);
      } else if (typeof code === "object") {
        Object.keys(code).forEach((sourceFileName) => {
          this.map.setSourceContent(sourceFileName, code[sourceFileName]);
        });
      }
    } else {
      this.map = null;
    }
  }
Example #26
0
    _.each(results, function (result) {
      var filename = result.filename;
      code += result.code + "\n";

      if (result.map) {
        var consumer = new sourceMap.SourceMapConsumer(result.map);

        map._sources.add(filename);
        map.setSourceContent(filename, result.actual);

        consumer.eachMapping(function (mapping) {
          map._mappings.add({
            generatedLine: mapping.generatedLine + offset,
            generatedColumn: mapping.generatedColumn,
            originalLine: mapping.originalLine,
            originalColumn: mapping.originalColumn,
            source: filename
          });
        });

        offset = code.split("\n").length;
      }
    });
Example #27
0
function generateSourceMap(filename, source, generated, sourceRoot) {
    const map = new SourceMapGenerator({
        file: filename.replace(/\\/g, '/'),
        sourceRoot: sourceRoot.replace(/\\/g, '/')
    });
    map.setSourceContent(filename, source);
    generated.split(splitRE).forEach((line, index) => {
        if (!emptyRE.test(line)) {
            map.addMapping({
                source: filename,
                original: {
                    line: index + 1,
                    column: 0
                },
                generated: {
                    line: index + 1,
                    column: 0
                }
            });
        }
    });
    return map.toJSON();
}
Example #28
0
function withSourceMap(src, compiled, name) {

  //return compiled;

  var compiledLines = compiled.split('\n');
  var generator = new SourceMapGenerator({file: name + '.js'});

  compiledLines.forEach(function(l, lineno) {
    var m = l.match(/^jade\.debug\.unshift\(\{ lineno: ([0-9]+)/);
    if (m) {
      generator.addMapping({
        generated: {
          line: lineno+2,
          column: 0
        },
        source: name,
        original: {
          line: Number(m[1]),
          column: 0
        }
      });
    }
    var debugRe = /jade\.debug\.(shift|unshift)\([^)]*\);?/;
    var match;
    while(match = l.match(debugRe)) {
      l = replaceMatchWith(match, '');
    }
    compiledLines[lineno] =l;
  });
  generator.setSourceContent(name, src);

  var map = convert.fromJSON(generator.toString());
  compiledLines.push(SUFFIX);
  compiledLines.push(map.toComment());
  return compiledLines.join('\n');
}
Example #29
0
function generateJs(sourcePath, fileContent) {
  var generator = new SourceMapGenerator({ file: sourcePath });
  var tokenizer = acorn.tokenizer(fileContent, { allowHashBang: true, locations: true });

  while (true) {
    var token = tokenizer.getToken();

    if (token.type.label === 'eof') {
      break;
    }
    var mapping = {
      original: token.loc.start,
      generated: token.loc.start,
      source: sourcePath,
    };
    if (token.type.label === 'name') {
      mapping.name = token.value;
    }
    generator.addMapping(mapping);
  }
  generator.setSourceContent(sourcePath, fileContent);

  return generator.toJSON();
}
Example #30
0
File: init.js Project: 4gekkman/R5
  function sourceMapInit(file, encoding, callback) {
    /*jshint validthis:true */

    // pass through if file is null or already has a source map
    if (file.isNull() || file.sourceMap) {
      this.push(file);
      return callback();
    }

    if (file.isStream()) {
      return callback(new Error(PLUGIN_NAME + '-init: Streaming not supported'));
    }

    if (options === undefined) {
      options = {};
    }
    debug(function() {
      return options;
    });

    var fileContent = file.contents.toString();
    var sourceMap;

    if (options.loadMaps) {
      debug('loadMaps');
      var sourcePath = ''; //root path for the sources in the map

      // Try to read inline source map
      sourceMap = convert.fromSource(fileContent, options.largeFile);
      if (sourceMap) {
        sourceMap = sourceMap.toObject();
        // sources in map are relative to the source file
        sourcePath = path.dirname(file.path);
        if (!options.largeFile) {
          fileContent = convert.removeComments(fileContent);
        }
      } else {
        // look for source map comment referencing a source map file
        var mapComment = convert.mapFileCommentRegex.exec(fileContent);

        var mapFile;
        if (mapComment) {
          mapFile = path.resolve(path.dirname(file.path), mapComment[1] || mapComment[2]);
          fileContent = convert.removeMapFileComments(fileContent);
          // if no comment try map file with same name as source file
        } else {
          mapFile = file.path + '.map';
        }

        // sources in external map are relative to map file
        sourcePath = path.dirname(mapFile);

        try {
          sourceMap = JSON.parse(stripBom(fs.readFileSync(mapFile, 'utf8')));
        } catch (e) {}
      }

      // fix source paths and sourceContent for imported source map
      if (sourceMap) {
        sourceMap.sourcesContent = sourceMap.sourcesContent || [];
        sourceMap.sources.forEach(function(source, i) {
          if (source.match(urlRegex)) {
            sourceMap.sourcesContent[i] = sourceMap.sourcesContent[i] || null;
            return;
          }
          var absPath = path.resolve(sourcePath, source);
          sourceMap.sources[i] = unixStylePath(path.relative(file.base, absPath));

          if (!sourceMap.sourcesContent[i]) {
            var sourceContent = null;
            if (sourceMap.sourceRoot) {
              if (sourceMap.sourceRoot.match(urlRegex)) {
                sourceMap.sourcesContent[i] = null;
                return;
              }
              absPath = path.resolve(sourcePath, sourceMap.sourceRoot, source);
            }

            // if current file: use content
            if (absPath === file.path) {
              sourceContent = fileContent;

              // else load content from file
            } else {
              try {
                if (options.debug)
                  debug('No source content for "' + source + '". Loading from file.');
                sourceContent = stripBom(fs.readFileSync(absPath, 'utf8'));
              } catch (e) {
                if (options.debug)
                  debug('warn: source file not found: ' + absPath);
                }
              }
            sourceMap.sourcesContent[i] = sourceContent;
          }
        });

        // remove source map comment from source
        file.contents = new Buffer(fileContent, 'utf8');
      }
    }

    if (!sourceMap && options.identityMap) {
      debug(function() {
        return 'identityMap';
      });
      var fileType = path.extname(file.path);
      var source = unixStylePath(file.relative);
      var generator = new SourceMapGenerator({file: source});

      if (fileType === '.js') {
        var tokenizer = acorn.tokenizer(fileContent, {locations: true});
        while (true) {
          var token = tokenizer.getToken();
          if (token.type.label === "eof")
            break;
          var mapping = {
            original: token.loc.start,
            generated: token.loc.start,
            source: source
          };
          if (token.type.label === 'name') {
            mapping.name = token.value;
          }
          generator.addMapping(mapping);
        }
        generator.setSourceContent(source, fileContent);
        sourceMap = generator.toJSON();

      } else if (fileType === '.css') {
        debug('css');
        var ast = css.parse(fileContent, {silent: true});
        debug(function() {
          return ast;
        });
        var registerTokens = function(ast) {
          if (ast.position) {
            generator.addMapping({original: ast.position.start, generated: ast.position.start, source: source});
          }

          function logAst(key, ast) {
            debug(function() {
              return 'key: ' + key;
            });
            debug(function() {
              return ast[key];
            });
          }

          for (var key in ast) {
            logAst(key, ast);
            if (key !== "position") {
              if (Object.prototype.toString.call(ast[key]) === '[object Object]') {
                registerTokens(ast[key]);
              } else if (Array.isArray(ast[key])) {
                debug(function() {
                  return "@@@@ ast[key] isArray @@@@";
                });
                for (var i = 0; i < ast[key].length; i++) {
                  registerTokens(ast[key][i]);
                }
              }
            }
          }
        };
        registerTokens(ast);
        generator.setSourceContent(source, fileContent);
        sourceMap = generator.toJSON();
      }
    }

    if (!sourceMap) {
      // Make an empty source map
      sourceMap = {
        version: 3,
        names: [],
        mappings: '',
        sources: [unixStylePath(file.relative)],
        sourcesContent: [fileContent]
      };
    }

    sourceMap.file = unixStylePath(file.relative);
    file.sourceMap = sourceMap;

    this.push(file);
    callback();
  }