You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sourcemap mapping is generated before node generates newline and indent #39170
copy above code to index.ts then run: tsc --target esnext --sourceMap index.ts
Expected behavior:
I expect that since this should just be removing types that the generated sourcemap could map all JS AST nodes start/end back to the original but at a minimum starts of statements, expressions, identifiers, blocks. Ideally for source map generation identifiers would 1 to 1 map to identifiers and not include type. Ideally starts should not include whitespace.
Actual behavior:
Missing closing braces in the try/finally block and the if in the finally block (since tsc 2.8).
Closing parens often start on prior lines ending newline instead of the paren in the original (since as far back as tsc 2.0).
Identifiers missing mapping at end when typing info was removed or there are default expressions.
The last one maybe considered a nice to have but is helpful with various tooling and to survive downstream transforms like rollup and minification.
My wild guess here is that mappings aren't emitted for the end of the generated AST nodes and often this works out because the next thing's start often works as an end. Not having the end be mappable is problematic as a lot of tooling tries to map the end as well and it is often missing.
After adding some instrumentation, it is clear what the issues are that are causing the above.
First, the ends of identifiers are skipped. Second, there are newlines and whitespace inserted after the start mapping is emitted and/or before the end mapping is emitted.
tsc --target esnext --sourceMap --newLine lf index.ts
emitSourcePos 0 0 (0) => 13 0 (376)
text span since last mapping:
gen: ''
src: 'export type AsyncFn<TResult> = () => PromiseLike<TResult>;\n' +
'\n' +
'export type RaceCancelFn = <TResult>(\n' +
' asyncFnOrPromise: AsyncFn<TResult> | PromiseLike<TResult>\n' +
') => Promise<TResult>;\n' +
'\n' +
'export type DisposeFn = () => void;\n' +
'\n' +
'export type DisposableExecutorFn<TResult> = (\n' +
' resolve: (value?: TResult | PromiseLike<TResult>) => void,\n' +
' reject: (reason?: any) => void\n' +
') => DisposeFn;\n' +
'\n'
pipelinePhase start 'VariableStatement' 374 635
emitSourcePos 0 0 (0) => 13 0 (376)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'VariableDeclarationList' 374 634
emitSourcePos 0 6 (6) => 13 6 (382)
text span since last mapping:
gen: 'const '
src: 'const '
pipelinePhase start 'VariableDeclaration' 381 634
emitSourcePos 0 6 (6) => 13 6 (382)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 381 396
pipelinePhase end 'Identifier' 381 396
emitSourcePos 0 20 (20) => 13 20 (396)
text span since last mapping:
gen: 'noopRaceCancel'
src: 'noopRaceCancel'
emitSourcePos 0 23 (23) => 13 37 (413)
text span since last mapping:
gen: ' = '
src: ': RaceCancelFn = '
pipelinePhase start 'ArrowFunction' 412 634
emitSourcePos 0 24 (24) => 14 2 (426)
text span since last mapping:
gen: '('
src: '<TResult>(\n '
pipelinePhase start 'Parameter' 423 483
emitSourcePos 0 24 (24) => 14 2 (426)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 423 442
pipelinePhase end 'Identifier' 423 442
emitSourcePos skipped
pipelinePhase end 'Parameter' 423 483
emitSourcePos 0 40 (40) => 14 59 (483)
text span since last mapping:
gen: 'asyncFnOrPromise'
src: 'asyncFnOrPromise: AsyncFn<TResult> | PromiseLike<TResult>'
emitSourcePos 0 42 (42) => 15 20 (504)
text span since last mapping:
gen: ') '
src: '\n): Promise<TResult> '
pipelinePhase start 'EqualsGreaterThanToken' 503 506
pipelinePhase end 'EqualsGreaterThanToken' 503 506
emitSourcePos 0 44 (44) => 15 22 (506)
text span since last mapping:
gen: '=>'
src: '=>'
emitSourcePos 0 45 (45) => 16 2 (509)
text span since last mapping:
gen: ''
src: '\n '
pipelinePhase start 'ConditionalExpression' 506 634
emitSourcePos 0 45 (45) => 16 2 (509)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'BinaryExpression' 506 547
emitSourcePos 0 45 (45) => 16 2 (509)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'TypeOfExpression' 506 532
emitSourcePos 0 52 (52) => 16 9 (516)
text span since last mapping:
gen: 'typeof '
src: 'typeof '
pipelinePhase start 'Identifier' 515 532
pipelinePhase end 'Identifier' 515 532
emitSourcePos 0 68 (68) => 16 25 (532)
text span since last mapping:
gen: 'asyncFnOrPromise'
src: 'asyncFnOrPromise'
pipelinePhase end 'TypeOfExpression' 506 532
emitSourcePos 0 68 (68) => 16 25 (532)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 0 73 (73) => 16 30 (537)
text span since last mapping:
gen: ' === '
src: ' === '
pipelinePhase start 'StringLiteral' 536 547
pipelinePhase end 'StringLiteral' 536 547
emitSourcePos 0 83 (83) => 16 40 (547)
text span since last mapping:
gen: '"function"'
src: '"function"'
pipelinePhase end 'BinaryExpression' 506 547
emitSourcePos 0 83 (83) => 16 40 (547)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 1 4 (84) => 17 4 (552)
text span since last mapping:
gen: '\n'
src: '\n '
pipelinePhase start 'QuestionToken' 547 553
pipelinePhase end 'QuestionToken' 547 553
emitSourcePos 1 5 (89) => 17 5 (553)
text span since last mapping:
gen: ' ?'
src: '?'
emitSourcePos 1 6 (90) => 17 6 (554)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'CallExpression' 553 594
emitSourcePos 1 6 (90) => 17 6 (554)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'PropertyAccessExpression' 553 576
emitSourcePos 1 6 (90) => 17 6 (554)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'CallExpression' 553 571
emitSourcePos 1 6 (90) => 17 6 (554)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'PropertyAccessExpression' 553 569
emitSourcePos 1 6 (90) => 17 6 (554)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 553 561
pipelinePhase end 'Identifier' 553 561
emitSourcePos 1 13 (97) => 17 13 (561)
text span since last mapping:
gen: 'Promise'
src: 'Promise'
emitSourcePos 1 14 (98) => 17 14 (562)
text span since last mapping:
gen: '.'
src: '.'
pipelinePhase start 'Identifier' 562 569
pipelinePhase end 'Identifier' 562 569
emitSourcePos 1 21 (105) => 17 21 (569)
text span since last mapping:
gen: 'resolve'
src: 'resolve'
pipelinePhase end 'PropertyAccessExpression' 553 569
emitSourcePos 1 21 (105) => 17 21 (569)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'CallExpression' 553 571
emitSourcePos 1 23 (107) => 17 23 (571)
text span since last mapping:
gen: '()'
src: '()'
emitSourcePos 1 24 (108) => 17 24 (572)
text span since last mapping:
gen: '.'
src: '.'
pipelinePhase start 'Identifier' 572 576
pipelinePhase end 'Identifier' 572 576
emitSourcePos 1 28 (112) => 17 28 (576)
text span since last mapping:
gen: 'then'
src: 'then'
pipelinePhase end 'PropertyAccessExpression' 553 576
emitSourcePos 1 28 (112) => 17 28 (576)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 1 29 (113) => 17 29 (577)
text span since last mapping:
gen: '('
src: '('
pipelinePhase start 'Identifier' 577 593
pipelinePhase end 'Identifier' 577 593
emitSourcePos 1 45 (129) => 17 45 (593)
text span since last mapping:
gen: 'asyncFnOrPromise'
src: 'asyncFnOrPromise'
pipelinePhase end 'CallExpression' 553 594
emitSourcePos 1 46 (130) => 17 46 (594)
text span since last mapping:
gen: ')'
src: ')'
emitSourcePos 2 4 (131) => 18 4 (599)
text span since last mapping:
gen: '\n'
src: '\n '
pipelinePhase start 'ColonToken' 594 600
pipelinePhase end 'ColonToken' 594 600
emitSourcePos 2 5 (136) => 18 5 (600)
text span since last mapping:
gen: ' :'
src: ':'
emitSourcePos 2 6 (137) => 18 6 (601)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'CallExpression' 600 634
emitSourcePos 2 6 (137) => 18 6 (601)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'PropertyAccessExpression' 600 616
emitSourcePos 2 6 (137) => 18 6 (601)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 600 608
pipelinePhase end 'Identifier' 600 608
emitSourcePos 2 13 (144) => 18 13 (608)
text span since last mapping:
gen: 'Promise'
src: 'Promise'
emitSourcePos 2 14 (145) => 18 14 (609)
text span since last mapping:
gen: '.'
src: '.'
pipelinePhase start 'Identifier' 609 616
pipelinePhase end 'Identifier' 609 616
emitSourcePos 2 21 (152) => 18 21 (616)
text span since last mapping:
gen: 'resolve'
src: 'resolve'
pipelinePhase end 'PropertyAccessExpression' 600 616
emitSourcePos 2 21 (152) => 18 21 (616)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 2 22 (153) => 18 22 (617)
text span since last mapping:
gen: '('
src: '('
pipelinePhase start 'Identifier' 617 633
pipelinePhase end 'Identifier' 617 633
emitSourcePos 2 38 (169) => 18 38 (633)
text span since last mapping:
gen: 'asyncFnOrPromise'
src: 'asyncFnOrPromise'
pipelinePhase end 'CallExpression' 600 634
emitSourcePos 2 39 (170) => 18 39 (634)
text span since last mapping:
gen: ')'
src: ')'
pipelinePhase end 'ConditionalExpression' 506 634
emitSourcePos 2 39 (170) => 18 39 (634)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'ArrowFunction' 412 634
emitSourcePos 2 39 (170) => 18 39 (634)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'VariableDeclaration' 381 634
emitSourcePos 2 39 (170) => 18 39 (634)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'VariableDeclarationList' 374 634
emitSourcePos 2 39 (170) => 18 39 (634)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'VariableStatement' 374 635
emitSourcePos 2 40 (171) => 18 40 (635)
text span since last mapping:
gen: ';'
src: ';'
emitSourcePos 3 0 (172) => 20 0 (637)
text span since last mapping:
gen: '\n'
src: '\n\n'
pipelinePhase start 'FunctionDeclaration' 635 1104
emitSourcePos 3 0 (172) => 20 0 (637)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'ExportKeyword' 635 643
pipelinePhase end 'ExportKeyword' 635 643
emitSourcePos 3 6 (178) => 20 6 (643)
text span since last mapping:
gen: 'export'
src: 'export'
emitSourcePos 3 7 (179) => 20 7 (644)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'DefaultKeyword' 643 651
pipelinePhase end 'DefaultKeyword' 643 651
emitSourcePos 3 14 (186) => 20 14 (651)
text span since last mapping:
gen: 'default'
src: 'default'
emitSourcePos 3 15 (187) => 20 15 (652)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'AsyncKeyword' 651 657
pipelinePhase end 'AsyncKeyword' 651 657
emitSourcePos 3 20 (192) => 20 20 (657)
text span since last mapping:
gen: 'async'
src: 'async'
emitSourcePos 3 30 (202) => 20 30 (667)
text span since last mapping:
gen: ' function '
src: ' function '
pipelinePhase start 'Identifier' 666 685
pipelinePhase end 'Identifier' 666 685
emitSourcePos 3 48 (220) => 20 48 (685)
text span since last mapping:
gen: 'cancellablePromise'
src: 'cancellablePromise'
emitSourcePos 3 49 (221) => 21 2 (698)
text span since last mapping:
gen: '('
src: '<TResult>(\n '
pipelinePhase start 'Parameter' 695 747
emitSourcePos 3 49 (221) => 21 2 (698)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 695 716
pipelinePhase end 'Identifier' 695 716
emitSourcePos skipped
pipelinePhase end 'Parameter' 695 747
emitSourcePos 3 67 (239) => 21 51 (747)
text span since last mapping:
gen: 'disposableExecutor'
src: 'disposableExecutor: DisposableExecutorFn<TResult>'
emitSourcePos 3 69 (241) => 22 2 (751)
text span since last mapping:
gen: ', '
src: ',\n '
pipelinePhase start 'Parameter' 748 792
emitSourcePos 3 69 (241) => 22 2 (751)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 748 761
pipelinePhase end 'Identifier' 748 761
emitSourcePos skipped
emitSourcePos 3 82 (254) => 22 29 (778)
text span since last mapping:
gen: 'raceCancel = '
src: 'raceCancel: RaceCancelFn = '
pipelinePhase start 'Identifier' 777 792
pipelinePhase end 'Identifier' 777 792
emitSourcePos 3 96 (268) => 22 43 (792)
text span since last mapping:
gen: 'noopRaceCancel'
src: 'noopRaceCancel'
pipelinePhase end 'Parameter' 748 792
emitSourcePos 3 96 (268) => 22 43 (792)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 4 4 (272) => 24 2 (817)
text span since last mapping:
gen: ') {\n'
src: '\n): Promise<TResult> {\n '
pipelinePhase start 'VariableStatement' 814 852
emitSourcePos 4 4 (272) => 24 2 (817)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'VariableDeclarationList' 814 851
emitSourcePos 4 8 (280) => 24 6 (821)
text span since last mapping:
gen: ' let '
src: 'let '
pipelinePhase start 'VariableDeclaration' 820 851
emitSourcePos 4 8 (280) => 24 6 (821)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 820 828
pipelinePhase end 'Identifier' 820 828
emitSourcePos 4 15 (287) => 24 13 (828)
text span since last mapping:
gen: 'dispose'
src: 'dispose'
pipelinePhase end 'VariableDeclaration' 820 851
emitSourcePos 4 15 (287) => 24 36 (851)
text span since last mapping:
gen: ''
src: ': DisposeFn | undefined'
pipelinePhase end 'VariableDeclarationList' 814 851
emitSourcePos 4 15 (287) => 24 36 (851)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'VariableStatement' 814 852
emitSourcePos 4 16 (288) => 24 37 (852)
text span since last mapping:
gen: ';'
src: ';'
emitSourcePos 5 4 (289) => 25 2 (855)
text span since last mapping:
gen: '\n'
src: '\n '
pipelinePhase start 'TryStatement' 852 1102
emitSourcePos 5 8 (297) => 25 6 (859)
text span since last mapping:
gen: ' try '
src: 'try '
pipelinePhase start 'Block' 858 1032
emitSourcePos 6 8 (299) => 26 4 (865)
text span since last mapping:
gen: '{\n'
src: '{\n '
pipelinePhase start 'ReturnStatement' 860 1028
emitSourcePos 6 15 (314) => 26 11 (872)
text span since last mapping:
gen: ' return '
src: 'return '
pipelinePhase start 'AwaitExpression' 871 1027
emitSourcePos 6 21 (320) => 26 17 (878)
text span since last mapping:
gen: 'await '
src: 'await '
pipelinePhase start 'CallExpression' 877 1027
emitSourcePos 6 21 (320) => 26 17 (878)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 877 888
pipelinePhase end 'Identifier' 877 888
emitSourcePos 6 31 (330) => 26 27 (888)
text span since last mapping:
gen: 'raceCancel'
src: 'raceCancel'
emitSourcePos 6 32 (331) => 27 6 (896)
text span since last mapping:
gen: '('
src: '(\n '
pipelinePhase start 'ArrowFunction' 889 1021
emitSourcePos 6 35 (334) => 27 9 (899)
text span since last mapping:
gen: '() '
src: '() '
pipelinePhase start 'EqualsGreaterThanToken' 898 901
pipelinePhase end 'EqualsGreaterThanToken' 898 901
emitSourcePos 6 37 (336) => 27 11 (901)
text span since last mapping:
gen: '=>'
src: '=>'
emitSourcePos 6 38 (337) => 28 8 (910)
text span since last mapping:
gen: ''
src: '\n '
pipelinePhase start 'NewExpression' 901 1021
emitSourcePos 6 42 (341) => 28 12 (914)
text span since last mapping:
gen: 'new '
src: 'new '
pipelinePhase start 'Identifier' 913 921
pipelinePhase end 'Identifier' 913 921
emitSourcePos 6 49 (348) => 28 19 (921)
text span since last mapping:
gen: 'Promise'
src: 'Promise'
emitSourcePos 6 50 (349) => 28 29 (931)
text span since last mapping:
gen: '('
src: '<TResult>('
pipelinePhase start 'ArrowFunction' 931 1020
emitSourcePos 6 51 (350) => 28 30 (932)
text span since last mapping:
gen: '('
src: '('
pipelinePhase start 'Parameter' 932 939
emitSourcePos 6 51 (350) => 28 30 (932)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 932 939
pipelinePhase end 'Identifier' 932 939
emitSourcePos 6 58 (357) => 28 37 (939)
text span since last mapping:
gen: 'resolve'
src: 'resolve'
pipelinePhase end 'Parameter' 932 939
emitSourcePos 6 58 (357) => 28 37 (939)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 6 60 (359) => 28 39 (941)
text span since last mapping:
gen: ', '
src: ', '
pipelinePhase start 'Parameter' 940 947
emitSourcePos 6 60 (359) => 28 39 (941)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 940 947
pipelinePhase end 'Identifier' 940 947
emitSourcePos 6 66 (365) => 28 45 (947)
text span since last mapping:
gen: 'reject'
src: 'reject'
pipelinePhase end 'Parameter' 940 947
emitSourcePos 6 66 (365) => 28 45 (947)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 6 68 (367) => 28 47 (949)
text span since last mapping:
gen: ') '
src: ') '
pipelinePhase start 'EqualsGreaterThanToken' 948 951
pipelinePhase end 'EqualsGreaterThanToken' 948 951
emitSourcePos 6 70 (369) => 28 49 (951)
text span since last mapping:
gen: '=>'
src: '=>'
emitSourcePos 7 12 (372) => 29 10 (964)
text span since last mapping:
gen: ' {\n'
src: ' {\n '
pipelinePhase start 'ExpressionStatement' 953 1010
emitSourcePos 7 12 (372) => 29 10 (964)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'BinaryExpression' 953 1009
emitSourcePos 7 12 (372) => 29 10 (964)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 953 971
pipelinePhase end 'Identifier' 953 971
emitSourcePos 7 19 (391) => 29 17 (971)
text span since last mapping:
gen: ' dispose'
src: 'dispose'
emitSourcePos 7 22 (394) => 29 20 (974)
text span since last mapping:
gen: ' = '
src: ' = '
pipelinePhase start 'CallExpression' 973 1009
emitSourcePos 7 22 (394) => 29 20 (974)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 973 992
pipelinePhase end 'Identifier' 973 992
emitSourcePos 7 40 (412) => 29 38 (992)
text span since last mapping:
gen: 'disposableExecutor'
src: 'disposableExecutor'
emitSourcePos 7 41 (413) => 29 39 (993)
text span since last mapping:
gen: '('
src: '('
pipelinePhase start 'Identifier' 993 1000
pipelinePhase end 'Identifier' 993 1000
emitSourcePos 7 48 (420) => 29 46 (1000)
text span since last mapping:
gen: 'resolve'
src: 'resolve'
emitSourcePos 7 50 (422) => 29 48 (1002)
text span since last mapping:
gen: ', '
src: ', '
pipelinePhase start 'Identifier' 1001 1008
pipelinePhase end 'Identifier' 1001 1008
emitSourcePos 7 56 (428) => 29 54 (1008)
text span since last mapping:
gen: 'reject'
src: 'reject'
pipelinePhase end 'CallExpression' 973 1009
emitSourcePos 7 57 (429) => 29 55 (1009)
text span since last mapping:
gen: ')'
src: ')'
pipelinePhase end 'BinaryExpression' 953 1009
emitSourcePos 7 57 (429) => 29 55 (1009)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'ExpressionStatement' 953 1010
emitSourcePos 7 58 (430) => 29 56 (1010)
text span since last mapping:
gen: ';'
src: ';'
emitSourcePos 8 8 (431) => 30 8 (1019)
text span since last mapping:
gen: '\n'
src: '\n '
emitToken start callback(token: 19)
emitToken end callback(token: 19)
emitSourcePos 8 9 (440) => 30 9 (1020)
text span since last mapping:
gen: ' }'
src: '}'
pipelinePhase end 'ArrowFunction' 931 1020
emitSourcePos 8 9 (440) => 30 9 (1020)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'NewExpression' 901 1021
emitSourcePos 8 10 (441) => 30 10 (1021)
text span since last mapping:
gen: ')'
src: ')'
pipelinePhase end 'ArrowFunction' 889 1021
emitSourcePos 8 10 (441) => 30 10 (1021)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'CallExpression' 877 1027
emitSourcePos 8 11 (442) => 31 5 (1027)
text span since last mapping:
gen: ')'
src: '\n )'
pipelinePhase end 'AwaitExpression' 871 1027
emitSourcePos 8 11 (442) => 31 5 (1027)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'ReturnStatement' 860 1028
emitSourcePos 8 12 (443) => 31 6 (1028)
text span since last mapping:
gen: ';'
src: ';'
pipelinePhase end 'Block' 858 1032
emitSourcePos 9 5 (449) => 32 3 (1032)
text span since last mapping:
gen: '\n }'
src: '\n }'
emitSourcePos 10 12 (462) => 32 12 (1041)
text span since last mapping:
gen: '\n finally '
src: ' finally '
pipelinePhase start 'Block' 1040 1102
emitSourcePos 11 8 (464) => 33 4 (1047)
text span since last mapping:
gen: '{\n'
src: '{\n '
pipelinePhase start 'IfStatement' 1042 1098
emitSourcePos 11 12 (476) => 33 8 (1051)
text span since last mapping:
gen: ' if ('
src: 'if ('
pipelinePhase start 'BinaryExpression' 1051 1072
emitSourcePos 11 12 (476) => 33 8 (1051)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 1051 1058
pipelinePhase end 'Identifier' 1051 1058
emitSourcePos 11 19 (483) => 33 15 (1058)
text span since last mapping:
gen: 'dispose'
src: 'dispose'
emitSourcePos 11 24 (488) => 33 20 (1063)
text span since last mapping:
gen: ' !== '
src: ' !== '
pipelinePhase start 'Identifier' 1062 1072
pipelinePhase end 'Identifier' 1062 1072
emitSourcePos 11 33 (497) => 33 29 (1072)
text span since last mapping:
gen: 'undefined'
src: 'undefined'
pipelinePhase end 'BinaryExpression' 1051 1072
emitSourcePos 11 33 (497) => 33 29 (1072)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 11 35 (499) => 33 31 (1074)
text span since last mapping:
gen: ') '
src: ') '
pipelinePhase start 'Block' 1073 1098
emitSourcePos 12 12 (501) => 34 6 (1082)
text span since last mapping:
gen: '{\n'
src: '{\n '
pipelinePhase start 'ExpressionStatement' 1075 1092
emitSourcePos 12 12 (501) => 34 6 (1082)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'CallExpression' 1075 1091
emitSourcePos 12 12 (501) => 34 6 (1082)
text span since last mapping:
gen: ''
src: ''
pipelinePhase start 'Identifier' 1075 1089
pipelinePhase end 'Identifier' 1075 1089
emitSourcePos 12 19 (520) => 34 13 (1089)
text span since last mapping:
gen: ' dispose'
src: 'dispose'
pipelinePhase end 'CallExpression' 1075 1091
emitSourcePos 12 21 (522) => 34 15 (1091)
text span since last mapping:
gen: '()'
src: '()'
pipelinePhase end 'ExpressionStatement' 1075 1092
emitSourcePos 12 22 (523) => 34 16 (1092)
text span since last mapping:
gen: ';'
src: ';'
pipelinePhase end 'Block' 1073 1098
emitSourcePos 13 9 (533) => 35 5 (1098)
text span since last mapping:
gen: '\n }'
src: '\n }'
pipelinePhase end 'IfStatement' 1042 1098
emitSourcePos 13 9 (533) => 35 5 (1098)
text span since last mapping:
gen: ''
src: ''
pipelinePhase end 'Block' 1040 1102
emitSourcePos 14 5 (539) => 36 3 (1102)
text span since last mapping:
gen: '\n }'
src: '\n }'
pipelinePhase end 'TryStatement' 852 1102
emitSourcePos 14 5 (539) => 36 3 (1102)
text span since last mapping:
gen: ''
src: ''
emitSourcePos 15 0 (540) => 37 0 (1103)
text span since last mapping:
gen: '\n'
src: '\n'
emitToken start callback(token: 19)
emitToken end callback(token: 19)
emitSourcePos 15 1 (541) => 37 1 (1104)
text span since last mapping:
gen: '}'
src: '}'
pipelinePhase end 'FunctionDeclaration' 635 1104
emitSourcePos 15 1 (541) => 37 1 (1104)
text span since last mapping:
gen: ''
src: ''
Ryan Cavanaugh (@RyanCavanaugh) I did a spike of a relatively simple fix to tsc.js that addressed most the issues above (all the invalid mappings). If I turned this into a PR, any chance of getting into the 3.x branch? I see this got labelled as 4.
Most the invalid mappings are caused by emitting a mapping for then next pos to be written then writeLine() being called which can be fixed by queuing adding the mapping until the first write method that isn't writeLine() and the remaining invalid mappings were caused by the src pos pointing to a newline which can be fixed by checking if it is a newline then forwarding it past the newline to the first non whitespace character. This fixes majority of all issues I know of.
changed the title [-]try finally block broken sourcemap[/-][+]sourcemap mapping is generated before node generates newline and indent[/+]on Jul 15, 2020
Ron Buckton (@rbuckton) the parenthesis is only part of the issue, the other part of this issue is newline and intent is applied after the mapping is emitting which breaks the mapping as it puts it on a new line and the col of the emitted mapping is out of bounds.
I got that part to work by post processing the out of bound mapping wrapping onto the next line. Then code coverage could map back to the TS.
I would be nice to add a test of using common build tooling that chains through source maps, like terser and c8.
Activity
krisselden commentedon Jun 19, 2020
Example of the issue the missing braces cause in code coverage
https://coveralls.io/builds/31527629/source?filename=race-cancellation/src/cancellablePromise.ts#L23
krisselden commentedon Jun 20, 2020
My wild guess here is that mappings aren't emitted for the end of the generated AST nodes and often this works out because the next thing's start often works as an end. Not having the end be mappable is problematic as a lot of tooling tries to map the end as well and it is often missing.
krisselden commentedon Jun 20, 2020
More context for why AST node end is important to map:
https://github.com/rollup/rollup/blob/2508884ab604df269c5450f7994faaf5e98873a9/src/ast/nodes/shared/Node.ts#L114
https://github.com/istanbuljs/v8-to-istanbul/blob/6592f82333944e1696ff61079728cde8e650b256/lib/v8-to-istanbul.js#L159
krisselden commentedon Jun 22, 2020
After adding some instrumentation, it is clear what the issues are that are causing the above.
First, the ends of identifiers are skipped. Second, there are newlines and whitespace inserted after the start mapping is emitted and/or before the end mapping is emitted.
krisselden commentedon Jun 23, 2020
Ryan Cavanaugh (@RyanCavanaugh) I did a spike of a relatively simple fix to tsc.js that addressed most the issues above (all the invalid mappings). If I turned this into a PR, any chance of getting into the 3.x branch? I see this got labelled as 4.
Most the invalid mappings are caused by emitting a mapping for then next pos to be written then writeLine() being called which can be fixed by queuing adding the mapping until the first write method that isn't writeLine() and the remaining invalid mappings were caused by the src pos pointing to a newline which can be fixed by checking if it is a newline then forwarding it past the newline to the first non whitespace character. This fixes majority of all issues I know of.
RyanCavanaugh commentedon Jun 23, 2020
Kris Selden (@krisselden) unless this is a regression, we'd generally only backport for critical bugs, which I don't think this qualifies
krisselden commentedon Jul 15, 2020
Workaround to post process the out of bound column mappings to the next line + indent https://github.com/krisselden/race-cancellation/blob/master/race-cancellation/scripts/fix-maps.cjs
[-]try finally block broken sourcemap[/-][+]sourcemap mapping is generated before node generates newline and indent[/+]8 remaining items
krisselden commentedon Sep 13, 2022
Ron Buckton (@rbuckton) the parenthesis is only part of the issue, the other part of this issue is newline and intent is applied after the mapping is emitting which breaks the mapping as it puts it on a new line and the col of the emitted mapping is out of bounds.
I got that part to work by post processing the out of bound mapping wrapping onto the next line. Then code coverage could map back to the TS.
I would be nice to add a test of using common build tooling that chains through source maps, like terser and c8.