mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Use the correct source when skipping trivia
A custom `SourceMapSource` can optionally provide its own `skipTrivia` function. If this is not provided then the compiler will use the default function designed for TypeScript source files. Previously, when calling this default function we were passing the current `sourceMapSource` rather than the specified `source` whose trivia needs to be skipped. This resulted in the `pos` being incorrectly calculated for external source files that need mapping. **Side note:** There are actually two possible constructors available for creating `SourceMapSource` objects. One of them defaults to an identity function for the `skipTrivia` function if it is not provided (see49689894d7/src/compiler/utilities.ts (L6972-L6976)) and the other one leaves the `skipTrivia` field `undefined` (see5fc8f1dd80/src/services/services.ts (L776-L797)) Unfortunately, it appears that the second of these two constructors is the one available when importing the "typescript" module in node.js code.
This commit is contained in:
@@ -4372,10 +4372,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips trivia such as comments and white-space that can optionally overriden by the source map source
|
||||
* Skips trivia such as comments and white-space that can be optionally overridden by the source-map source
|
||||
*/
|
||||
function skipSourceTrivia(source: SourceMapSource, pos: number): number {
|
||||
return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(sourceMapSource.text, pos);
|
||||
return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(source.text, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -129,5 +129,34 @@ namespace ts {
|
||||
},
|
||||
{ sourceMap: true }
|
||||
);
|
||||
|
||||
emitsCorrectly("skipTriviaExternalSourceFiles",
|
||||
[
|
||||
{
|
||||
file: "source.ts",
|
||||
// The source file contains preceding trivia (e.g. whitespace) to try to confuse the `skipSourceTrivia` function.
|
||||
text: " original;"
|
||||
},
|
||||
],
|
||||
{
|
||||
before: [
|
||||
context => node => visitNode(node, function visitor(node: Node): Node {
|
||||
if (isIdentifier(node) && node.text === "original") {
|
||||
const newNode = createIdentifier("changed");
|
||||
setSourceMapRange(newNode, {
|
||||
pos: 0,
|
||||
end: 7,
|
||||
// Do not provide a custom skipTrivia function for `source`.
|
||||
source: createSourceMapSource("another.html", "changed;")
|
||||
});
|
||||
return newNode;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
]
|
||||
},
|
||||
{ sourceMap: true }
|
||||
);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// [source.js.map]
|
||||
{"version":3,"file":"source.js","sourceRoot":"","sources":["source.ts","another.html"],"names":[],"mappings":"ACAA,OAAO,CDAW"}
|
||||
|
||||
// [source.js]
|
||||
changed;
|
||||
//# sourceMappingURL=source.js.map
|
||||
Reference in New Issue
Block a user