Clamp calculated sourcemap positions rather than throwing (#28583)
* Clamp calculated sourcemap positions rather than throwing, to allow the underlying file to drift out of date with the sourcemap without a crash * Clamp line as well
This commit is contained in:
parent
12f3d0d54c
commit
cd08a22ef5
|
@ -342,12 +342,29 @@ namespace ts {
|
|||
}
|
||||
|
||||
/* @internal */
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string): number {
|
||||
export function getPositionOfLineAndCharacterWithEdits(sourceFile: SourceFileLike, line: number, character: number): number {
|
||||
return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, /*allowEdits*/ true);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string, allowEdits?: true): number {
|
||||
if (line < 0 || line >= lineStarts.length) {
|
||||
if (allowEdits) {
|
||||
// Clamp line to nearest allowable value
|
||||
line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
}
|
||||
}
|
||||
|
||||
const res = lineStarts[line] + character;
|
||||
if (allowEdits) {
|
||||
// Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
|
||||
// TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
|
||||
// apply them to the computed position to improve accuracy
|
||||
return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
|
||||
}
|
||||
if (line < lineStarts.length - 1) {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
}
|
||||
|
|
|
@ -608,7 +608,7 @@ namespace ts {
|
|||
|
||||
function processMapping(mapping: Mapping): MappedPosition {
|
||||
const generatedPosition = generatedFile !== undefined
|
||||
? getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter)
|
||||
? getPositionOfLineAndCharacterWithEdits(generatedFile, mapping.generatedLine, mapping.generatedCharacter)
|
||||
: -1;
|
||||
let source: string | undefined;
|
||||
let sourcePosition: number | undefined;
|
||||
|
@ -617,7 +617,7 @@ namespace ts {
|
|||
const sourceFile = host.getSourceFileLike(sourceFilePath);
|
||||
source = map.sources[mapping.sourceIndex];
|
||||
sourcePosition = sourceFile !== undefined
|
||||
? getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter)
|
||||
? getPositionOfLineAndCharacterWithEdits(sourceFile, mapping.sourceLine, mapping.sourceCharacter)
|
||||
: -1;
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/// <reference path="../fourslash.ts" />
|
||||
|
||||
// @Filename: /node_modules/a/dist/index.d.ts
|
||||
////export declare class Foo {
|
||||
//// bar: any;
|
||||
////}
|
||||
//////# sourceMappingURL=index.d.ts.map
|
||||
|
||||
// @Filename: /node_modules/a/dist/index.d.ts.map
|
||||
////{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,GAAG,MAAC;CACP"}
|
||||
|
||||
// @Filename: /node_modules/a/src/index.ts
|
||||
////export class /*2*/Foo {
|
||||
////}
|
||||
////
|
||||
|
||||
// @Filename: /node_modules/a/package.json
|
||||
////{
|
||||
//// "name": "a",
|
||||
//// "version": "0.0.0",
|
||||
//// "private": true,
|
||||
//// "main": "dist",
|
||||
//// "types": "dist"
|
||||
////}
|
||||
|
||||
// @Filename: /index.ts
|
||||
////import { Foo/*1*/ } from "a";
|
||||
|
||||
goTo.file("/index.ts");
|
||||
|
||||
goTo.marker("1");
|
||||
verify.goToDefinitionIs("2"); // getDefinitionAndBoundSpan
|
Loading…
Reference in a new issue