diff options
author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/istanbul-lib-source-maps/lib | |
parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/istanbul-lib-source-maps/lib')
6 files changed, 710 insertions, 0 deletions
diff --git a/node_modules/istanbul-lib-source-maps/lib/get-mapping.js b/node_modules/istanbul-lib-source-maps/lib/get-mapping.js new file mode 100644 index 0000000..c24f618 --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/get-mapping.js @@ -0,0 +1,182 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +const pathutils = require('./pathutils'); +const { + GREATEST_LOWER_BOUND, + LEAST_UPPER_BOUND +} = require('source-map').SourceMapConsumer; + +/** + * AST ranges are inclusive for start positions and exclusive for end positions. + * Source maps are also logically ranges over text, though interacting with + * them is generally achieved by working with explicit positions. + * + * When finding the _end_ location of an AST item, the range behavior is + * important because what we're asking for is the _end_ of whatever range + * corresponds to the end location we seek. + * + * This boils down to the following steps, conceptually, though the source-map + * library doesn't expose primitives to do this nicely: + * + * 1. Find the range on the generated file that ends at, or exclusively + * contains the end position of the AST node. + * 2. Find the range on the original file that corresponds to + * that generated range. + * 3. Find the _end_ location of that original range. + */ +function originalEndPositionFor(sourceMap, generatedEnd) { + // Given the generated location, find the original location of the mapping + // that corresponds to a range on the generated file that overlaps the + // generated file end location. Note however that this position on its + // own is not useful because it is the position of the _start_ of the range + // on the original file, and we want the _end_ of the range. + const beforeEndMapping = originalPositionTryBoth( + sourceMap, + generatedEnd.line, + generatedEnd.column - 1 + ); + if (beforeEndMapping.source === null) { + return null; + } + + // Convert that original position back to a generated one, with a bump + // to the right, and a rightward bias. Since 'generatedPositionFor' searches + // for mappings in the original-order sorted list, this will find the + // mapping that corresponds to the one immediately after the + // beforeEndMapping mapping. + const afterEndMapping = sourceMap.generatedPositionFor({ + source: beforeEndMapping.source, + line: beforeEndMapping.line, + column: beforeEndMapping.column + 1, + bias: LEAST_UPPER_BOUND + }); + if ( + // If this is null, it means that we've hit the end of the file, + // so we can use Infinity as the end column. + afterEndMapping.line === null || + // If these don't match, it means that the call to + // 'generatedPositionFor' didn't find any other original mappings on + // the line we gave, so consider the binding to extend to infinity. + sourceMap.originalPositionFor(afterEndMapping).line !== + beforeEndMapping.line + ) { + return { + source: beforeEndMapping.source, + line: beforeEndMapping.line, + column: Infinity + }; + } + + // Convert the end mapping into the real original position. + return sourceMap.originalPositionFor(afterEndMapping); +} + +/** + * Attempts to determine the original source position, first + * returning the closest element to the left (GREATEST_LOWER_BOUND), + * and next returning the closest element to the right (LEAST_UPPER_BOUND). + */ +function originalPositionTryBoth(sourceMap, line, column) { + const mapping = sourceMap.originalPositionFor({ + line, + column, + bias: GREATEST_LOWER_BOUND + }); + if (mapping.source === null) { + return sourceMap.originalPositionFor({ + line, + column, + bias: LEAST_UPPER_BOUND + }); + } else { + return mapping; + } +} + +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} generatedLocation the original location Object + * @returns {Object} the remapped location Object + */ +function getMapping(sourceMap, generatedLocation, origFile) { + if (!generatedLocation) { + return null; + } + + if ( + isInvalidPosition(generatedLocation.start) || + isInvalidPosition(generatedLocation.end) + ) { + return null; + } + + const start = originalPositionTryBoth( + sourceMap, + generatedLocation.start.line, + generatedLocation.start.column + ); + let end = originalEndPositionFor(sourceMap, generatedLocation.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: generatedLocation.end.line, + column: generatedLocation.end.column, + bias: LEAST_UPPER_BOUND + }); + 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 + } + } + }; +} + +module.exports = getMapping; diff --git a/node_modules/istanbul-lib-source-maps/lib/map-store.js b/node_modules/istanbul-lib-source-maps/lib/map-store.js new file mode 100644 index 0000000..a99b79a --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/map-store.js @@ -0,0 +1,226 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +const path = require('path'); +const fs = require('fs'); +const debug = require('debug')('istanbuljs'); +const { SourceMapConsumer } = require('source-map'); +const pathutils = require('./pathutils'); +const { SourceMapTransformer } = require('./transformer'); + +/** + * Tracks source maps for registered files + */ +class MapStore { + /** + * @param {Object} opts [opts=undefined] options. + * @param {Boolean} opts.verbose [opts.verbose=false] verbose mode + * @param {String} opts.baseDir [opts.baseDir=null] alternate base directory + * to resolve sourcemap files + * @param {Class} opts.SourceStore [opts.SourceStore=Map] class to use for + * SourceStore. Must support `get`, `set` and `clear` methods. + * @param {Array} opts.sourceStoreOpts [opts.sourceStoreOpts=[]] arguments + * to use in the SourceStore constructor. + * @constructor + */ + constructor(opts) { + opts = { + baseDir: null, + verbose: false, + SourceStore: Map, + sourceStoreOpts: [], + ...opts + }; + this.baseDir = opts.baseDir; + this.verbose = opts.verbose; + this.sourceStore = new opts.SourceStore(...opts.sourceStoreOpts); + this.data = Object.create(null); + this.sourceFinder = this.sourceFinder.bind(this); + } + + /** + * Registers a source map URL with this store. It makes some input sanity checks + * and silently fails on malformed input. + * @param transformedFilePath - the file path for which the source map is valid. + * This must *exactly* match the path stashed for the coverage object to be + * useful. + * @param sourceMapUrl - the source map URL, **not** a comment + */ + registerURL(transformedFilePath, sourceMapUrl) { + const d = 'data:'; + + if ( + sourceMapUrl.length > d.length && + sourceMapUrl.substring(0, d.length) === d + ) { + const b64 = 'base64,'; + const pos = sourceMapUrl.indexOf(b64); + if (pos > 0) { + this.data[transformedFilePath] = { + type: 'encoded', + data: sourceMapUrl.substring(pos + b64.length) + }; + } else { + debug(`Unable to interpret source map URL: ${sourceMapUrl}`); + } + + return; + } + + const dir = path.dirname(path.resolve(transformedFilePath)); + const file = path.resolve(dir, sourceMapUrl); + this.data[transformedFilePath] = { type: 'file', data: file }; + } + + /** + * Registers a source map object with this store. Makes some basic sanity checks + * and silently fails on malformed input. + * @param transformedFilePath - the file path for which the source map is valid + * @param sourceMap - the source map object + */ + registerMap(transformedFilePath, sourceMap) { + if (sourceMap && sourceMap.version) { + this.data[transformedFilePath] = { + type: 'object', + data: sourceMap + }; + } else { + debug( + 'Invalid source map object: ' + + JSON.stringify(sourceMap, null, 2) + ); + } + } + + /** + * Retrieve a source map object from this store. + * @param filePath - the file path for which the source map is valid + * @returns {Object} a parsed source map object + */ + getSourceMapSync(filePath) { + try { + if (!this.data[filePath]) { + return; + } + + const d = this.data[filePath]; + if (d.type === 'file') { + return JSON.parse(fs.readFileSync(d.data, 'utf8')); + } + + if (d.type === 'encoded') { + return JSON.parse(Buffer.from(d.data, 'base64').toString()); + } + + /* The caller might delete properties */ + return { + ...d.data + }; + } catch (error) { + debug('Error returning source map for ' + filePath); + debug(error.stack); + + return; + } + } + + /** + * Add inputSourceMap property to coverage data + * @param coverageData - the __coverage__ object + * @returns {Object} a parsed source map object + */ + addInputSourceMapsSync(coverageData) { + Object.entries(coverageData).forEach(([filePath, data]) => { + if (data.inputSourceMap) { + return; + } + + const sourceMap = this.getSourceMapSync(filePath); + if (sourceMap) { + data.inputSourceMap = sourceMap; + /* This huge property is not needed. */ + delete data.inputSourceMap.sourcesContent; + } + }); + } + + sourceFinder(filePath) { + const content = this.sourceStore.get(filePath); + if (content !== undefined) { + return content; + } + + if (path.isAbsolute(filePath)) { + return fs.readFileSync(filePath, 'utf8'); + } + + return fs.readFileSync( + pathutils.asAbsolute(filePath, this.baseDir), + 'utf8' + ); + } + + /** + * Transforms the coverage map provided into one that refers to original + * sources when valid mappings have been registered with this store. + * @param {CoverageMap} coverageMap - the coverage map to transform + * @returns {Promise<CoverageMap>} the transformed coverage map + */ + async transformCoverage(coverageMap) { + const hasInputSourceMaps = coverageMap + .files() + .some( + file => coverageMap.fileCoverageFor(file).data.inputSourceMap + ); + + if (!hasInputSourceMaps && Object.keys(this.data).length === 0) { + return coverageMap; + } + + const transformer = new SourceMapTransformer( + async (filePath, coverage) => { + try { + const obj = + coverage.data.inputSourceMap || + this.getSourceMapSync(filePath); + if (!obj) { + return null; + } + + const smc = new SourceMapConsumer(obj); + smc.sources.forEach(s => { + const content = smc.sourceContentFor(s); + if (content) { + const sourceFilePath = pathutils.relativeTo( + s, + filePath + ); + this.sourceStore.set(sourceFilePath, content); + } + }); + + return smc; + } catch (error) { + debug('Error returning source map for ' + filePath); + debug(error.stack); + + return null; + } + } + ); + + return await transformer.transform(coverageMap); + } + + /** + * Disposes temporary resources allocated by this map store + */ + dispose() { + this.sourceStore.clear(); + } +} + +module.exports = { MapStore }; diff --git a/node_modules/istanbul-lib-source-maps/lib/mapped.js b/node_modules/istanbul-lib-source-maps/lib/mapped.js new file mode 100644 index 0000000..73f256c --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/mapped.js @@ -0,0 +1,113 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +const { FileCoverage } = require('istanbul-lib-coverage').classes; + +function locString(loc) { + return [ + loc.start.line, + loc.start.column, + loc.end.line, + loc.end.column + ].join(':'); +} + +class MappedCoverage extends FileCoverage { + constructor(pathOrObj) { + super(pathOrObj); + + this.meta = { + last: { + s: 0, + f: 0, + b: 0 + }, + seen: {} + }; + } + + addStatement(loc, hits) { + const key = 's:' + locString(loc); + const { meta } = this; + let index = meta.seen[key]; + + if (index === undefined) { + index = meta.last.s; + meta.last.s += 1; + meta.seen[key] = index; + this.statementMap[index] = this.cloneLocation(loc); + } + + this.s[index] = this.s[index] || 0; + this.s[index] += hits; + return index; + } + + addFunction(name, decl, loc, hits) { + const key = 'f:' + locString(decl); + const { meta } = this; + let index = meta.seen[key]; + + if (index === undefined) { + index = meta.last.f; + meta.last.f += 1; + meta.seen[key] = index; + name = name || `(unknown_${index})`; + this.fnMap[index] = { + name, + decl: this.cloneLocation(decl), + loc: this.cloneLocation(loc) + }; + } + + this.f[index] = this.f[index] || 0; + this.f[index] += hits; + return index; + } + + addBranch(type, loc, branchLocations, hits) { + const key = ['b', ...branchLocations.map(l => locString(l))].join(':'); + const { meta } = this; + let index = meta.seen[key]; + if (index === undefined) { + index = meta.last.b; + meta.last.b += 1; + meta.seen[key] = index; + this.branchMap[index] = { + loc, + type, + locations: branchLocations.map(l => this.cloneLocation(l)) + }; + } + + if (!this.b[index]) { + this.b[index] = branchLocations.map(() => 0); + } + + hits.forEach((hit, i) => { + this.b[index][i] += hit; + }); + return index; + } + + /* Returns a clone of the location object with only the attributes of interest */ + cloneLocation(loc) { + return { + start: { + line: loc.start.line, + column: loc.start.column + }, + end: { + line: loc.end.line, + column: loc.end.column + } + }; + } +} + +module.exports = { + MappedCoverage +}; diff --git a/node_modules/istanbul-lib-source-maps/lib/pathutils.js b/node_modules/istanbul-lib-source-maps/lib/pathutils.js new file mode 100644 index 0000000..7dca05a --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/pathutils.js @@ -0,0 +1,21 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +const path = require('path'); + +module.exports = { + isAbsolute: path.isAbsolute, + asAbsolute(file, baseDir) { + return path.isAbsolute(file) + ? file + : path.resolve(baseDir || process.cwd(), file); + }, + relativeTo(file, origFile) { + return path.isAbsolute(file) + ? file + : path.resolve(path.dirname(origFile), file); + } +}; diff --git a/node_modules/istanbul-lib-source-maps/lib/transform-utils.js b/node_modules/istanbul-lib-source-maps/lib/transform-utils.js new file mode 100644 index 0000000..0933093 --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/transform-utils.js @@ -0,0 +1,21 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +function getUniqueKey(pathname) { + return pathname.replace(/[\\/]/g, '_'); +} + +function getOutput(cache) { + return Object.values(cache).reduce( + (output, { file, mappedCoverage }) => ({ + ...output, + [file]: mappedCoverage + }), + {} + ); +} + +module.exports = { getUniqueKey, getOutput }; 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 0000000..6f63538 --- /dev/null +++ b/node_modules/istanbul-lib-source-maps/lib/transformer.js @@ -0,0 +1,147 @@ +/* + Copyright 2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; + +const debug = require('debug')('istanbuljs'); +const libCoverage = require('istanbul-lib-coverage'); +const { MappedCoverage } = require('./mapped'); +const getMapping = require('./get-mapping'); +const { getUniqueKey, getOutput } = require('./transform-utils'); + +class SourceMapTransformer { + constructor(finder, opts = {}) { + this.finder = finder; + this.baseDir = opts.baseDir || process.cwd(); + this.resolveMapping = opts.getMapping || getMapping; + } + + processFile(fc, sourceMap, coverageMapper) { + let changes = 0; + + Object.entries(fc.statementMap).forEach(([s, loc]) => { + const hits = fc.s[s]; + const mapping = this.resolveMapping(sourceMap, loc, fc.path); + + if (mapping) { + changes += 1; + const mappedCoverage = coverageMapper(mapping.source); + mappedCoverage.addStatement(mapping.loc, hits); + } + }); + + Object.entries(fc.fnMap).forEach(([f, fnMeta]) => { + const hits = fc.f[f]; + const mapping = this.resolveMapping( + sourceMap, + fnMeta.decl, + fc.path + ); + + const spanMapping = this.resolveMapping( + sourceMap, + fnMeta.loc, + fc.path + ); + + if ( + mapping && + spanMapping && + mapping.source === spanMapping.source + ) { + changes += 1; + const mappedCoverage = coverageMapper(mapping.source); + mappedCoverage.addFunction( + fnMeta.name, + mapping.loc, + spanMapping.loc, + hits + ); + } + }); + + Object.entries(fc.branchMap).forEach(([b, branchMeta]) => { + const hits = fc.b[b]; + const locs = []; + const mappedHits = []; + let source; + let skip; + + branchMeta.locations.forEach((loc, i) => { + const mapping = this.resolveMapping(sourceMap, loc, fc.path); + if (mapping) { + if (!source) { + source = mapping.source; + } + + if (mapping.source !== source) { + skip = true; + } + + locs.push(mapping.loc); + mappedHits.push(hits[i]); + } + }); + + const locMapping = branchMeta.loc + ? this.resolveMapping(sourceMap, branchMeta.loc, fc.path) + : null; + + if (!skip && locs.length > 0) { + changes += 1; + const mappedCoverage = coverageMapper(source); + mappedCoverage.addBranch( + branchMeta.type, + locMapping ? locMapping.loc : locs[0], + locs, + mappedHits + ); + } + }); + + return changes > 0; + } + + async transform(coverageMap) { + const uniqueFiles = {}; + const getMappedCoverage = file => { + const key = getUniqueKey(file); + if (!uniqueFiles[key]) { + uniqueFiles[key] = { + file, + mappedCoverage: new MappedCoverage(file) + }; + } + + return uniqueFiles[key].mappedCoverage; + }; + + for (const file of coverageMap.files()) { + const fc = coverageMap.fileCoverageFor(file); + const sourceMap = await this.finder(file, fc); + + if (sourceMap) { + const changed = this.processFile( + fc, + sourceMap, + getMappedCoverage + ); + if (!changed) { + debug(`File [${file}] ignored, nothing could be mapped`); + } + } else { + uniqueFiles[getUniqueKey(file)] = { + file, + mappedCoverage: new MappedCoverage(fc) + }; + } + } + + return libCoverage.createCoverageMap(getOutput(uniqueFiles)); + } +} + +module.exports = { + SourceMapTransformer +}; |