@@ -16,60 +16,54 @@ import {
16
16
TransformOperation ,
17
17
} from './interfaces' ;
18
18
19
-
20
- // Typescript below 2.7.0 needs a workaround.
21
- const tsVersionParts = ts . version . split ( '.' ) . map ( p => Number ( p ) ) ;
22
- const visitEachChild = tsVersionParts [ 0 ] <= 2 && tsVersionParts [ 1 ] < 7
23
- ? visitEachChildWorkaround
24
- : ts . visitEachChild ;
25
-
26
19
export function makeTransform (
27
20
standardTransform : StandardTransform ,
28
21
getTypeChecker ?: ( ) => ts . TypeChecker ,
29
22
) : ts . TransformerFactory < ts . SourceFile > {
30
-
31
23
return ( context : ts . TransformationContext ) : ts . Transformer < ts . SourceFile > => {
32
24
const transformer : ts . Transformer < ts . SourceFile > = ( sf : ts . SourceFile ) => {
33
25
const ops : TransformOperation [ ] = standardTransform ( sf ) ;
34
- const removeOps = ops
35
- . filter ( ( op ) => op . kind === OPERATION_KIND . Remove ) as RemoveNodeOperation [ ] ;
36
- const addOps = ops . filter ( ( op ) => op . kind === OPERATION_KIND . Add ) as AddNodeOperation [ ] ;
37
- const replaceOps = ops
38
- . filter ( ( op ) => op . kind === OPERATION_KIND . Replace ) as ReplaceNodeOperation [ ] ;
26
+ const removeOps = ops . filter (
27
+ op => op . kind === OPERATION_KIND . Remove ,
28
+ ) as RemoveNodeOperation [ ] ;
29
+ const addOps = ops . filter ( op => op . kind === OPERATION_KIND . Add ) as AddNodeOperation [ ] ;
30
+ const replaceOps = ops . filter (
31
+ op => op . kind === OPERATION_KIND . Replace ,
32
+ ) as ReplaceNodeOperation [ ] ;
39
33
40
34
// If nodes are removed, elide the imports as well.
41
35
// Mainly a workaround for https://github.com/Microsoft/TypeScript/issues/17552.
42
36
// WARNING: this assumes that replaceOps DO NOT reuse any of the nodes they are replacing.
43
37
// This is currently true for transforms that use replaceOps (replace_bootstrap and
44
38
// replace_resources), but may not be true for new transforms.
45
39
if ( getTypeChecker && removeOps . length + replaceOps . length > 0 ) {
46
- const removedNodes = removeOps . concat ( replaceOps ) . map ( ( op ) => op . target ) ;
40
+ const removedNodes = removeOps . concat ( replaceOps ) . map ( op => op . target ) ;
47
41
removeOps . push ( ...elideImports ( sf , removedNodes , getTypeChecker ) ) ;
48
42
}
49
43
50
- const visitor : ts . Visitor = ( node ) => {
44
+ const visitor : ts . Visitor = node => {
51
45
let modified = false ;
52
46
let modifiedNodes = [ node ] ;
53
47
// Check if node should be dropped.
54
- if ( removeOps . find ( ( op ) => op . target === node ) ) {
48
+ if ( removeOps . find ( op => op . target === node ) ) {
55
49
modifiedNodes = [ ] ;
56
50
modified = true ;
57
51
}
58
52
59
53
// Check if node should be replaced (only replaces with first op found).
60
- const replace = replaceOps . find ( ( op ) => op . target === node ) ;
54
+ const replace = replaceOps . find ( op => op . target === node ) ;
61
55
if ( replace ) {
62
56
modifiedNodes = [ replace . replacement ] ;
63
57
modified = true ;
64
58
}
65
59
66
60
// Check if node should be added to.
67
- const add = addOps . filter ( ( op ) => op . target === node ) ;
61
+ const add = addOps . filter ( op => op . target === node ) ;
68
62
if ( add . length > 0 ) {
69
63
modifiedNodes = [
70
- ...add . filter ( ( op ) => op . before ) . map ( ( ( op ) => op . before ) ) ,
64
+ ...add . filter ( op => op . before ) . map ( op => op . before ) ,
71
65
...modifiedNodes ,
72
- ...add . filter ( ( op ) => op . after ) . map ( ( ( op ) => op . after ) ) ,
66
+ ...add . filter ( op => op . after ) . map ( op => op . after ) ,
73
67
] as ts . Node [ ] ;
74
68
modified = true ;
75
69
}
@@ -79,7 +73,7 @@ export function makeTransform(
79
73
return modifiedNodes ;
80
74
} else {
81
75
// Otherwise return node as is and visit children.
82
- return visitEachChild ( node , visitor , context ) ;
76
+ return ts . visitEachChild ( node , visitor , context ) ;
83
77
}
84
78
} ;
85
79
@@ -91,7 +85,7 @@ export function makeTransform(
91
85
const result = ts . visitNode ( sf , visitor ) ;
92
86
93
87
// If we removed any decorators, we need to clean up the decorator arrays.
94
- if ( removeOps . some ( ( op ) => op . target . kind === ts . SyntaxKind . Decorator ) ) {
88
+ if ( removeOps . some ( op => op . target . kind === ts . SyntaxKind . Decorator ) ) {
95
89
cleanupDecorators ( result ) ;
96
90
}
97
91
@@ -102,52 +96,11 @@ export function makeTransform(
102
96
} ;
103
97
}
104
98
105
- /**
106
- * This is a version of `ts.visitEachChild` that works that calls our version
107
- * of `updateSourceFileNode`, so that typescript doesn't lose type information
108
- * for property decorators.
109
- * See https://github.com/Microsoft/TypeScript/issues/17384 (fixed by
110
- * https://github.com/Microsoft/TypeScript/pull/20314 and released in TS 2.7.0) and
111
- * https://github.com/Microsoft/TypeScript/issues/17551 (fixed by
112
- * https://github.com/Microsoft/TypeScript/pull/18051 and released on TS 2.5.0).
113
- */
114
- function visitEachChildWorkaround (
115
- node : ts . Node ,
116
- visitor : ts . Visitor ,
117
- context : ts . TransformationContext ,
118
- ) {
119
-
120
- if ( node . kind === ts . SyntaxKind . SourceFile ) {
121
- const sf = node as ts . SourceFile ;
122
- const statements = ts . visitLexicalEnvironment ( sf . statements , visitor , context ) ;
123
-
124
- if ( statements === sf . statements ) {
125
- return sf ;
126
- }
127
- // Note: Need to clone the original file (and not use `ts.updateSourceFileNode`)
128
- // as otherwise TS fails when resolving types for decorators.
129
- const sfClone = ts . getMutableClone ( sf ) ;
130
- sfClone . statements = statements ;
131
-
132
- return sfClone ;
133
- }
134
-
135
- return ts . visitEachChild ( node , visitor , context ) ;
136
- }
137
-
138
-
139
- // 1) If TS sees an empty decorator array, it will still emit a `__decorate` call.
99
+ // If TS sees an empty decorator array, it will still emit a `__decorate` call.
140
100
// This seems to be a TS bug.
141
- // 2) Also ensure nodes with modified decorators have parents
142
- // built in TS transformers assume certain nodes have parents (fixed in TS 2.7+)
143
101
function cleanupDecorators ( node : ts . Node ) {
144
- if ( node . decorators ) {
145
- if ( node . decorators . length == 0 ) {
146
- node . decorators = undefined ;
147
- } else if ( node . parent == undefined ) {
148
- const originalNode = ts . getParseTreeNode ( node ) ;
149
- node . parent = originalNode . parent ;
150
- }
102
+ if ( node . decorators && node . decorators . length === 0 ) {
103
+ node . decorators = undefined ;
151
104
}
152
105
153
106
ts . forEachChild ( node , node => cleanupDecorators ( node ) ) ;
0 commit comments