1
1
import ts from 'typescript' ;
2
- import { evaluate , hasModifier } from './utils' ;
2
+ import { evaluate , getModifier } from './utils' ;
3
3
4
4
export default function ( program : ts . Program , pluginOptions ?: unknown ) {
5
5
return ( ctx : ts . TransformationContext ) => {
@@ -12,18 +12,16 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
12
12
if ( ! ts . isEnumDeclaration ( node ) ) {
13
13
return ts . visitEachChild ( node , visitor , ctx ) ;
14
14
}
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 ;
21
19
22
20
if ( ambient ) {
23
21
return ts . visitEachChild ( node , stripConstKeyword , ctx ) ;
24
22
}
25
23
26
- return transformEnum ( node ) ;
24
+ return transformEnum ( node , [ exportModifier , constModifier ] ) ;
27
25
}
28
26
} ;
29
27
} ;
@@ -32,10 +30,10 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
32
30
return node . kind === ts . SyntaxKind . ConstKeyword ? undefined : node ;
33
31
}
34
32
35
- function transformEnum ( node : ts . EnumDeclaration ) {
33
+ function transformEnum ( node : ts . EnumDeclaration , modifiers : ts . Modifier [ ] ) {
36
34
const members = node . members ;
37
35
const known = new Map < string , number | string > ( ) ;
38
- const ast = [ ] ;
36
+ const properties : ts . PropertyAssignment [ ] = [ ] ;
39
37
let lastValue : string | number = - 1 ;
40
38
41
39
for ( const member of members ) {
@@ -44,19 +42,18 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
44
42
}
45
43
const name = member . name . getText ( ) ;
46
44
let value : string | number ;
45
+ let valueExpr : ts . Expression ;
47
46
48
47
if ( member . initializer ) {
49
48
value = evaluate ( member . initializer , known ) ;
50
- let valueExpr : ts . Expression ;
49
+
51
50
if ( typeof value === 'number' ) {
52
51
valueExpr = ts . factory . createNumericLiteral ( value ) ;
53
52
lastValue = value ;
54
53
} else if ( typeof value === 'string' ) {
55
54
valueExpr = ts . factory . createStringLiteral ( value ) ;
56
55
lastValue = value ;
57
56
} else throw new Error ( 'Unsupported member value' ) ;
58
-
59
- ast . push ( ts . factory . createPropertyAssignment ( name , valueExpr ) ) ;
60
57
} else {
61
58
if ( typeof lastValue === 'string' ) {
62
59
throw new Error ( 'Invalid enum' ) ;
@@ -72,29 +69,24 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
72
69
* }
73
70
*/
74
71
value = ++ lastValue ;
75
- ast . push (
76
- ts . factory . createPropertyAssignment (
77
- name ,
78
- ts . factory . createNumericLiteral ( value ) ,
79
- ) ,
80
- ) ;
72
+ valueExpr = ts . factory . createNumericLiteral ( value ) ;
81
73
}
74
+ const assignment = ts . factory . createPropertyAssignment ( name , valueExpr ) ;
75
+ ts . setSourceMapRange ( assignment , ts . getSourceMapRange ( member ) ) ;
76
+ properties . push ( assignment ) ;
82
77
known . set ( name , value ) ;
83
78
}
84
79
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 ,
90
82
ts . factory . createVariableDeclarationList (
91
83
[
92
84
ts . factory . createVariableDeclaration (
93
85
node . name ,
94
86
undefined ,
95
87
undefined ,
96
88
ts . factory . createAsExpression (
97
- ts . factory . createObjectLiteralExpression ( ast , true ) ,
89
+ ts . factory . createObjectLiteralExpression ( properties , true ) ,
98
90
ts . factory . createTypeReferenceNode (
99
91
ts . factory . createIdentifier ( 'const' ) ,
100
92
undefined ,
@@ -105,5 +97,8 @@ export default function(program: ts.Program, pluginOptions?: unknown) {
105
97
ts . NodeFlags . Const ,
106
98
) ,
107
99
) ;
100
+
101
+ ts . setSourceMapRange ( result , ts . getSourceMapRange ( node ) ) ;
102
+ return result ;
108
103
}
109
104
}
0 commit comments