aboutsummaryrefslogtreecommitdiff
path: root/node_modules/istanbul-lib-source-maps/lib/transformer.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/istanbul-lib-source-maps/lib/transformer.js')
-rw-r--r--node_modules/istanbul-lib-source-maps/lib/transformer.js181
1 files changed, 181 insertions, 0 deletions
diff --git a/node_modules/istanbul-lib-source-maps/lib/transformer.js b/node_modules/istanbul-lib-source-maps/lib/transformer.js
new file mode 100644
index 000000000..748805949
--- /dev/null
+++ b/node_modules/istanbul-lib-source-maps/lib/transformer.js
@@ -0,0 +1,181 @@
+/*
+ Copyright 2015, Yahoo Inc.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+"use strict";
+
+var debug = require('debug')('istanbuljs'),
+ pathutils = require('./pathutils'),
+ libCoverage = require('istanbul-lib-coverage'),
+ MappedCoverage = require('./mapped').MappedCoverage;
+
+function isInvalidPosition (pos) {
+ return !pos || typeof pos.line !== "number" || typeof pos.column !== "number" || pos.line < 0 || pos.column < 0;
+}
+
+/**
+ * determines the original position for a given location
+ * @param {SourceMapConsumer} sourceMap the source map
+ * @param {Object} location the original location Object
+ * @returns {Object} the remapped location Object
+ */
+function getMapping(sourceMap, location, origFile) {
+
+ if (!location) {
+ return null;
+ }
+
+ if (isInvalidPosition(location.start) || isInvalidPosition(location.end)) {
+ return null;
+ }
+
+ var start = sourceMap.originalPositionFor(location.start),
+ end = sourceMap.originalPositionFor(location.end);
+
+ /* istanbul ignore if: edge case too hard to test for */
+ if (!(start && end)) {
+ return null;
+ }
+ if (!(start.source && end.source)) {
+ return null;
+ }
+ if (start.source !== end.source) {
+ return null;
+ }
+
+ /* istanbul ignore if: edge case too hard to test for */
+ if (start.line === null || start.column === null) {
+ return null;
+ }
+ /* istanbul ignore if: edge case too hard to test for */
+ if (end.line === null || end.column === null) {
+ return null;
+ }
+
+ if (start.line === end.line && start.column === end.column) {
+ end = sourceMap.originalPositionFor({
+ line: location.end.line,
+ column: location.end.column,
+ bias: 2
+ });
+ end.column = end.column - 1;
+ }
+
+ return {
+ source: pathutils.relativeTo(start.source, origFile),
+ loc: {
+ start: {
+ line: start.line,
+ column: start.column
+ },
+ end: {
+ line: end.line,
+ column: end.column
+ }
+ }
+ };
+}
+
+function SourceMapTransformer(finder, opts) {
+ opts = opts || {};
+ this.finder = finder;
+ this.baseDir = opts.baseDir || process.cwd();
+}
+
+SourceMapTransformer.prototype.processFile = function (fc, sourceMap, coverageMapper) {
+ var changes = 0;
+
+ Object.keys(fc.statementMap).forEach(function (s) {
+ var loc = fc.statementMap[s],
+ hits = fc.s[s],
+ mapping = getMapping(sourceMap, loc, fc.path),
+ mappedCoverage;
+
+ if (mapping) {
+ changes += 1;
+ mappedCoverage = coverageMapper(mapping.source);
+ mappedCoverage.addStatement(mapping.loc, hits);
+ }
+ });
+
+ Object.keys(fc.fnMap).forEach(function (f) {
+ var fnMeta = fc.fnMap[f],
+ hits = fc.f[f],
+ mapping = getMapping(sourceMap, fnMeta.decl, fc.path),
+ spanMapping = getMapping(sourceMap, fnMeta.loc, fc.path),
+ mappedCoverage;
+
+ if (mapping && spanMapping && mapping.source === spanMapping.source) {
+ changes += 1;
+ mappedCoverage = coverageMapper(mapping.source);
+ mappedCoverage.addFunction(fnMeta.name, mapping.loc, spanMapping.loc, hits);
+ }
+ });
+
+ Object.keys(fc.branchMap).forEach(function (b) {
+ var branchMeta = fc.branchMap[b],
+ source,
+ hits = fc.b[b],
+ mapping,
+ locs = [],
+ mappedHits = [],
+ mappedCoverage,
+ skip,
+ i;
+ for (i = 0; i < branchMeta.locations.length; i += 1) {
+ mapping = getMapping(sourceMap, branchMeta.locations[i], fc.path);
+ if (mapping) {
+ if (!source) {
+ source = mapping.source;
+ }
+ if (mapping.source !== source) {
+ skip = true;
+ }
+ locs.push(mapping.loc);
+ mappedHits.push(hits[i]);
+ }
+ }
+ if (!skip && locs.length > 0) {
+ changes += 1;
+ mappedCoverage = coverageMapper(source);
+ mappedCoverage.addBranch(branchMeta.type, locs[0] /* XXX */, locs, mappedHits);
+ }
+ });
+
+ return changes > 0;
+};
+
+SourceMapTransformer.prototype.transform = function (coverageMap) {
+ var that = this,
+ finder = this.finder,
+ output = {},
+ getMappedCoverage = function (file) {
+ if (!output[file]) {
+ output[file] = new MappedCoverage(file);
+ }
+ return output[file];
+ };
+
+ coverageMap.files().forEach(function (file) {
+ var fc = coverageMap.fileCoverageFor(file),
+ sourceMap = finder(file),
+ changed;
+
+ if (!sourceMap) {
+ output[file] = fc;
+ return;
+ }
+
+ changed = that.processFile(fc, sourceMap, getMappedCoverage);
+ if (!changed) {
+ debug('File [' + file + '] ignored, nothing could be mapped');
+ }
+ });
+ return libCoverage.createCoverageMap(output);
+};
+
+module.exports = {
+ create: function (finder, opts) {
+ return new SourceMapTransformer(finder, opts);
+ }
+};