Skip to content

Commit 75a9d4e

Browse files
authored
Merge pull request #1 from Fonger/feat/sourcemap
feat: support SourceMap mapping
2 parents 7c89ebd + 98de50d commit 75a9d4e

File tree

8 files changed

+64
-36
lines changed

8 files changed

+64
-36
lines changed

.codecov.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coverage:
2+
status:
3+
project:
4+
default:
5+
target: 80%
6+
patch:
7+
default:
8+
target: 80%

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ jobs:
2525
- name: Upload coverage report to Codecov
2626
uses: codecov/[email protected]
2727
with:
28+
files: coverage/lcov.info
2829
fail_ci_if_error: true

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ module.exports = {
88
},
99
},
1010
testPathIgnorePatterns: ['dist'],
11+
coverageReporters: ['text', process.env.CI === 'true' ? 'lcovonly' : 'lcov'],
1112
};

src/__snapshots__/transform.test.ts.snap

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ export declare enum ComputedEnum {
2121
J = \\"12\\",
2222
K = 1
2323
}
24-
export declare enum RegularEnum {
24+
declare enum NonExportEnum {
2525
A = 0,
2626
B = 1
2727
}
28+
declare function SomeFunc(inlineSomeEnum: SomeEnum, inlineComputedEnum: ComputedEnum): SomeEnum.D | ComputedEnum | NonExportEnum;
29+
export default SomeFunc;
2830
"
2931
`;
3032

@@ -49,10 +51,21 @@ export const ComputedEnum = {
4951
J: \\"12\\",
5052
K: 1
5153
};
52-
export var RegularEnum;
53-
(function (RegularEnum) {
54-
RegularEnum[RegularEnum[\\"A\\"] = 0] = \\"A\\";
55-
RegularEnum[RegularEnum[\\"B\\"] = 1] = \\"B\\";
56-
})(RegularEnum || (RegularEnum = {}));
57-
"
54+
const Value = 0.5;
55+
var NonExportEnum;
56+
(function (NonExportEnum) {
57+
NonExportEnum[NonExportEnum[\\"A\\"] = 0] = \\"A\\";
58+
NonExportEnum[NonExportEnum[\\"B\\"] = 1] = \\"B\\";
59+
})(NonExportEnum || (NonExportEnum = {}));
60+
function SomeFunc(inlineSomeEnum, inlineComputedEnum) {
61+
if (inlineSomeEnum === 0 /* A */)
62+
return 1000 /* D */;
63+
if (inlineComputedEnum === -2 /* D */)
64+
return 4 /* E */;
65+
return Math.random() > Value ? NonExportEnum.A : NonExportEnum.B;
66+
}
67+
export default SomeFunc;
68+
//# sourceMappingURL=const-enum.js.map"
5869
`;
70+
71+
exports[`transform export const enum into object literal test-case/const-enum.js.map 1`] = `"{\\"version\\":3,\\"file\\":\\"const-enum.js\\",\\"sourceRoot\\":\\"\\",\\"sources\\":[\\"const-enum.ts\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,MAAM,OAAY,QAAQ;IACxB,IAAC;IACD,IAAC;IACD,UAAW;IACX,OAAQ;IACR,OAAC;EACF;AAED,MAAM,OAAY,YAAY;IAC5B,IAAC;IACD,IAAC;IACD,IAAC;IACD,KAAU;IACV,IAAU;IACV,KAAc;IACd,OAAuB;IACvB,KAA4B;IAC5B,MAAgB;IAChB,OAAa;IACb,IAAoB;EACrB;AAED,MAAM,KAAK,GAAG,GAAG,CAAC;AAElB,IAAK,aAGJ;AAHD,WAAK,aAAa;IAChB,2CAAC,CAAA;IACD,2CAAC,CAAA;AACH,CAAC,EAHI,aAAa,KAAb,aAAa,QAGjB;AAED,SAAS,QAAQ,CAAC,cAAwB,EAAE,kBAAgC;IAC1E,IAAI,cAAc,cAAe;QAAE,oBAAkB;IACrD,IAAI,kBAAkB,eAAmB;QAAE,iBAAsB;IACjE,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,eAAe,QAAQ,CAAC\\"}"`;

src/transform.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import ts from 'typescript';
22
import transform from './transform';
3-
43
describe('transform export const enum into object literal', () => {
54
const output = compile('test-case/const-enum.ts');
65

@@ -20,6 +19,7 @@ function compile(fileName: string): Output {
2019
module: ts.ModuleKind.ES2015,
2120
preserveConstEnums: true,
2221
declaration: true,
22+
sourceMap: true,
2323
moduleResolution: ts.ModuleResolutionKind.NodeJs,
2424
},
2525
});

src/transform.ts

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import ts from 'typescript';
2-
import { evaluate, hasModifier } from './utils';
2+
import { evaluate, getModifier } from './utils';
33

44
export default function(program: ts.Program, pluginOptions?: unknown) {
55
return (ctx: ts.TransformationContext) => {
@@ -12,18 +12,16 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
1212
if (!ts.isEnumDeclaration(node)) {
1313
return ts.visitEachChild(node, visitor, ctx);
1414
}
15-
if (
16-
!hasModifier(node, ts.SyntaxKind.ExportKeyword)
17-
|| !hasModifier(node, ts.SyntaxKind.ConstKeyword)
18-
) {
19-
return node;
20-
}
15+
const exportModifier = getModifier(node, ts.SyntaxKind.ExportKeyword);
16+
if (!exportModifier) return node;
17+
const constModifier = getModifier(node, ts.SyntaxKind.ConstKeyword);
18+
if (!constModifier) return node;
2119

2220
if (ambient) {
2321
return ts.visitEachChild(node, stripConstKeyword, ctx);
2422
}
2523

26-
return transformEnum(node);
24+
return transformEnum(node, [exportModifier, constModifier]);
2725
}
2826
};
2927
};
@@ -32,10 +30,10 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
3230
return node.kind === ts.SyntaxKind.ConstKeyword ? undefined : node;
3331
}
3432

35-
function transformEnum(node: ts.EnumDeclaration) {
33+
function transformEnum(node: ts.EnumDeclaration, modifiers: ts.Modifier[]) {
3634
const members = node.members;
3735
const known = new Map<string, number | string>();
38-
const ast = [];
36+
const properties: ts.PropertyAssignment[] = [];
3937
let lastValue: string | number = -1;
4038

4139
for (const member of members) {
@@ -44,19 +42,18 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
4442
}
4543
const name = member.name.getText();
4644
let value: string | number;
45+
let valueExpr: ts.Expression;
4746

4847
if (member.initializer) {
4948
value = evaluate(member.initializer, known);
50-
let valueExpr: ts.Expression;
49+
5150
if (typeof value === 'number') {
5251
valueExpr = ts.factory.createNumericLiteral(value);
5352
lastValue = value;
5453
} else if (typeof value === 'string') {
5554
valueExpr = ts.factory.createStringLiteral(value);
5655
lastValue = value;
5756
} else throw new Error('Unsupported member value');
58-
59-
ast.push(ts.factory.createPropertyAssignment(name, valueExpr));
6057
} else {
6158
if (typeof lastValue === 'string') {
6259
throw new Error('Invalid enum');
@@ -72,29 +69,24 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
7269
* }
7370
*/
7471
value = ++lastValue;
75-
ast.push(
76-
ts.factory.createPropertyAssignment(
77-
name,
78-
ts.factory.createNumericLiteral(value),
79-
),
80-
);
72+
valueExpr = ts.factory.createNumericLiteral(value);
8173
}
74+
const assignment = ts.factory.createPropertyAssignment(name, valueExpr);
75+
ts.setSourceMapRange(assignment, ts.getSourceMapRange(member));
76+
properties.push(assignment);
8277
known.set(name, value);
8378
}
8479

85-
return ts.factory.createVariableStatement(
86-
[
87-
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
88-
ts.factory.createModifier(ts.SyntaxKind.ConstKeyword),
89-
],
80+
const result = ts.factory.createVariableStatement(
81+
modifiers,
9082
ts.factory.createVariableDeclarationList(
9183
[
9284
ts.factory.createVariableDeclaration(
9385
node.name,
9486
undefined,
9587
undefined,
9688
ts.factory.createAsExpression(
97-
ts.factory.createObjectLiteralExpression(ast, true),
89+
ts.factory.createObjectLiteralExpression(properties, true),
9890
ts.factory.createTypeReferenceNode(
9991
ts.factory.createIdentifier('const'),
10092
undefined,
@@ -105,5 +97,8 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
10597
ts.NodeFlags.Const,
10698
),
10799
);
100+
101+
ts.setSourceMapRange(result, ts.getSourceMapRange(node));
102+
return result;
108103
}
109104
}

src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ export function evaluate(
6969
return undefined;
7070
}
7171

72-
export function hasModifier(node: ts.Node, modifier: ts.SyntaxKind): boolean {
72+
export function getModifier(node: ts.Node, modifier: ts.SyntaxKind) {
7373
return (
7474
node.modifiers
75-
&& node.modifiers.some((mod: ts.Modifier) => mod.kind === modifier)
75+
&& node.modifiers.find((mod: ts.Modifier) => mod.kind === modifier)
7676
);
7777
}

test-case/const-enum.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ export const enum ComputedEnum {
2020
K = B & 1000 + H / 2,
2121
}
2222

23-
export enum RegularEnum {
23+
const Value = 0.5;
24+
25+
enum NonExportEnum {
2426
A,
2527
B,
2628
}
29+
30+
function SomeFunc(inlineSomeEnum: SomeEnum, inlineComputedEnum: ComputedEnum) {
31+
if (inlineSomeEnum === SomeEnum.A) return SomeEnum.D;
32+
if (inlineComputedEnum === ComputedEnum.D) return ComputedEnum.E;
33+
return Math.random() > Value ? NonExportEnum.A : NonExportEnum.B;
34+
}
35+
36+
export default SomeFunc;

0 commit comments

Comments
 (0)