Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit db21564

Browse files
Use fuzzy search when using sourcemaps (#306)
Now the input file in a directory tree associated with the output file described by sourcemap can be identified, even if the input file's path does not match exactly with what is expected from the sourcemap. Fixes: #226 PR-URL: #306
1 parent f13d122 commit db21564

File tree

3 files changed

+64
-25
lines changed

3 files changed

+64
-25
lines changed

src/agent/sourcemapper.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import * as fs from 'fs';
1919
import * as _ from 'lodash';
2020
import * as path from 'path';
2121
import * as sourceMap from 'source-map';
22+
import {findScriptsFuzzy} from './v8debugapi';
2223

2324
/** @define {string} */ const MAP_EXT = '.map';
2425

@@ -127,6 +128,31 @@ export class SourceMapper {
127128
this.infoMap_ = new Map();
128129
}
129130

131+
/**
132+
* Used to get the information about the transpiled file from a given input
133+
* source file provided there isn't any ambiguity with associating the input
134+
* path to exactly one output transpiled file.
135+
*
136+
* @param inputPath The (possibly relative) path to the original source file.
137+
* @return The `MapInfoInput` object that describes the transpiled file
138+
* associated with the specified input path. `null` is returned if either
139+
* zero files are associated with the input path or if more than one file
140+
* could possibly be associated with the given input path.
141+
*/
142+
private getMappingInfo(inputPath: string): MapInfoInput|null {
143+
if (this.infoMap_.has(path.normalize(inputPath))) {
144+
return this.infoMap_.get(inputPath) as MapInfoInput;
145+
}
146+
147+
const matches =
148+
findScriptsFuzzy(inputPath, Array.from(this.infoMap_.keys()));
149+
if (matches.length === 1) {
150+
return this.infoMap_.get(matches[0]) as MapInfoInput;
151+
}
152+
153+
return null;
154+
}
155+
130156
/**
131157
* Used to determine if the source file specified by the given path has
132158
* a .map file and an output file associated with it.
@@ -141,7 +167,7 @@ export class SourceMapper {
141167
* relative to the process's current working directory.
142168
*/
143169
hasMappingInfo(inputPath: string): boolean {
144-
return this.infoMap_.has(path.normalize(inputPath));
170+
return this.getMappingInfo(inputPath) !== null;
145171
}
146172

147173
/**
@@ -166,12 +192,11 @@ export class SourceMapper {
166192
mappingInfo(inputPath: string, lineNumber: number, colNumber: number):
167193
MapInfoOutput|null {
168194
inputPath = path.normalize(inputPath);
169-
if (!this.hasMappingInfo(inputPath)) {
195+
const entry = this.getMappingInfo(inputPath);
196+
if (entry === null) {
170197
return null;
171198
}
172199

173-
// TODO: `entry` could be `undefined` here. Address this case.
174-
const entry = this.infoMap_.get(inputPath) as any as MapInfoInput;
175200
const sourcePos = {
176201
source: path.relative(path.dirname(entry.mapFile), inputPath),
177202
line: lineNumber + 1, // the SourceMapConsumer expects the line number

src/agent/v8debugapi.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,6 @@ export function findScripts(
743743
* available.
744744
* @return {array<string>} list of files that match.
745745
*/
746-
// Exposed for unit testing.
747746
export function findScriptsFuzzy(
748747
scriptPath: string, fileList: string[]): string[] {
749748
let matches = fileList;

test/test-sourcemapper.js

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,30 @@ var path = require('path');
2121

2222
var SourceMapper = require('../build/src/agent/sourcemapper.js');
2323

24+
var BASE_PATH = path.join(__dirname, 'fixtures', 'sourcemapper');
25+
2426
/**
25-
* @param {string} tool The name of the tool that was used to generate the
27+
* @param {string} tool The name of the tool that was used to generate the
2628
* given sourcemap data
27-
* @param {string} mapFilePath The path to the sourcemap file of a
29+
* @param {string} relativeMapFilePath The path to the sourcemap file of a
2830
* transpilation to test
29-
* @param {string} inputFilePath The path to the input file that was
31+
* @param {string} relativeInputFilePath The path to the input file that was
3032
* transpiled to generate the specified sourcemap file
31-
* @param {string} outputFilePath The path to the output file that was
32-
* generated during the transpilation process that constructed the
33+
* @param {string} relativeOutputFilePath The path to the output file that was
34+
* generated during the transpilation process that constructed the
3335
* specified sourcemap file
3436
* @param {Array.<Array.<number, number>>} inToOutLineNums An array of arrays
3537
* where each element in the array is a pair of numbers. The first number
3638
* in the pair is the line number from the input file and the second number
3739
* in the pair is the expected line number in the corresponding output file
38-
*
40+
*
3941
* Note: The line numbers are zero-based
4042
*/
41-
function testTool(tool, mapFilePath, inputFilePath, outputFilePath, inToOutLineNums) {
43+
function testTool(tool, relativeMapFilePath, relativeInputFilePath, relativeOutputFilePath, inToOutLineNums) {
44+
var mapFilePath = path.join(BASE_PATH, relativeMapFilePath);
45+
var inputFilePath = path.join(BASE_PATH, relativeInputFilePath);
46+
var outputFilePath = path.join(BASE_PATH, relativeOutputFilePath);
47+
4248
describe('sourcemapper for tool ' + tool, function() {
4349
var sourcemapper;
4450

@@ -62,11 +68,21 @@ function testTool(tool, mapFilePath, inputFilePath, outputFilePath, inToOutLineN
6268
done();
6369
});
6470

65-
it('for tool ' + tool +
71+
it('for tool ' + tool +
72+
' it states that it has mapping info for files with a path' +
73+
' similar to a path it knows about',
74+
function(done) {
75+
assert.equal(sourcemapper.hasMappingInfo(relativeInputFilePath), true);
76+
var movedPath = path.join('/some/other/base/dir/', relativeInputFilePath);
77+
assert.equal(sourcemapper.hasMappingInfo(movedPath), true);
78+
done();
79+
});
80+
81+
it('for tool ' + tool +
6682
' it states that it does not have mapping info for a file it ' +
6783
'doesn\'t recognize',
6884
function(done) {
69-
assert.equal(sourcemapper.hasMappingInfo('INVALID_' + inputFilePath), false);
85+
assert.equal(sourcemapper.hasMappingInfo(inputFilePath + '_INVALID'), false);
7086
done();
7187
});
7288

@@ -90,11 +106,10 @@ function testTool(tool, mapFilePath, inputFilePath, outputFilePath, inToOutLineN
90106
});
91107
}
92108

93-
var basePath = path.join(__dirname, 'fixtures', 'sourcemapper');
94-
testTool('Babel',
95-
path.join(basePath, 'babel', 'out.js.map'),
96-
path.join(basePath, 'babel', 'in.js'),
97-
path.join(basePath, 'babel', 'out.js'), [
109+
testTool('Babel',
110+
path.join('babel', 'out.js.map'),
111+
path.join('babel', 'in.js'),
112+
path.join('babel', 'out.js'), [
98113
[1, 14],
99114
[2, 15],
100115
[3, 16],
@@ -148,9 +163,9 @@ testTool('Babel',
148163
]);
149164

150165
testTool('Typescript',
151-
path.join(basePath, 'typescript', 'out.js.map'),
152-
path.join(basePath, 'typescript', 'in.ts'),
153-
path.join(basePath, 'typescript', 'out.js'), [
166+
path.join('typescript', 'out.js.map'),
167+
path.join('typescript', 'in.ts'),
168+
path.join('typescript', 'out.js'), [
154169
[1, 5],
155170
[2, 6],
156171
[3, 9],
@@ -167,9 +182,9 @@ testTool('Typescript',
167182
]);
168183

169184
testTool('Coffeescript',
170-
path.join(basePath, 'coffeescript', 'in.js.map'),
171-
path.join(basePath, 'coffeescript', 'in.coffee'),
172-
path.join(basePath, 'coffeescript', 'in.js'),[
185+
path.join('coffeescript', 'in.js.map'),
186+
path.join('coffeescript', 'in.coffee'),
187+
path.join('coffeescript', 'in.js'),[
173188
[1, 1],
174189
[2, 7],
175190
[3, 8],

0 commit comments

Comments
 (0)