Skip to content

Commit ebd1662

Browse files
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 (see https://github.com/Microsoft/TypeScript/blob/49689894d747714d6b2b8461b9033020efec9625/src/compiler/utilities.ts#L6972-L6976) and the other one leaves the `skipTrivia` field `undefined` (see https://github.com/Microsoft/TypeScript/blob/5fc8f1dd801dbacfe7e2d624f80b7a6a3868d180/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.
1 parent 2f6c65e commit ebd1662

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

src/compiler/emitter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4372,10 +4372,10 @@ namespace ts {
43724372
}
43734373

43744374
/**
4375-
* Skips trivia such as comments and white-space that can optionally overriden by the source map source
4375+
* Skips trivia such as comments and white-space that can optionally overridden by the source map source
43764376
*/
43774377
function skipSourceTrivia(source: SourceMapSource, pos: number): number {
4378-
return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(sourceMapSource.text, pos);
4378+
return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(source.text, pos);
43794379
}
43804380

43814381
/**

src/testRunner/unittests/customTransforms.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,34 @@ namespace ts {
129129
},
130130
{ sourceMap: true }
131131
);
132+
133+
emitsCorrectly("skipTriviaExternalSourceFiles",
134+
[
135+
{
136+
file: "source.ts",
137+
// The source file contains preceding trivia (e.g. whitespace) to try to confuse the `skipSourceTrivia` function.
138+
text: " original;"
139+
},
140+
],
141+
{
142+
before: [
143+
context => node => visitNode(node, function visitor(node: Node): Node {
144+
if (isIdentifier(node) && node.text === "original") {
145+
const newNode = createIdentifier("changed");
146+
setSourceMapRange(newNode, {
147+
pos: 0,
148+
end: 7,
149+
// Do not provide a custom skipTrivia function for `source`.
150+
source: createSourceMapSource("another.html", "changed;")
151+
});
152+
return newNode;
153+
}
154+
return visitEachChild(node, visitor, context);
155+
})
156+
]
157+
},
158+
{ sourceMap: true }
159+
);
160+
132161
});
133162
}

tests/baselines/reference/customTransforms/skipTriviaExternalSourceFiles.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)