5
5
* Use of this source code is governed by an MIT-style license that can be
6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
- import { tags } from '@angular-devkit/core' ;
9
8
import * as ts from 'typescript' ;
10
9
10
+ // emit helper for `import Name from "foo"`
11
+ // importName is marked as an internal property but is needed for the tslib import.
12
+ const importDefaultHelper : ts . UnscopedEmitHelper & { importName ?: string } = {
13
+ name : 'typescript:commonjsimportdefault' ,
14
+ importName : '__importDefault' ,
15
+ scoped : false ,
16
+ text : `
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };` ,
20
+ } ;
21
+
11
22
export function replaceResources (
12
23
shouldTransform : ( fileName : string ) => boolean ,
13
24
getTypeChecker : ( ) => ts . TypeChecker ,
14
25
directTemplateLoading = false ,
15
26
) : ts . TransformerFactory < ts . SourceFile > {
16
-
17
27
return ( context : ts . TransformationContext ) => {
18
28
const typeChecker = getTypeChecker ( ) ;
19
29
20
30
const visitNode : ts . Visitor = ( node : ts . Node ) => {
21
31
if ( ts . isClassDeclaration ( node ) ) {
22
- const decorators = ts . visitNodes (
23
- node . decorators ,
24
- ( node : ts . Decorator ) => visitDecorator ( node , typeChecker , directTemplateLoading ) ,
32
+ const decorators = ts . visitNodes ( node . decorators , ( node : ts . Decorator ) =>
33
+ visitDecorator ( context , node , typeChecker , directTemplateLoading ) ,
25
34
) ;
26
35
27
36
return ts . updateClassDeclaration (
@@ -38,22 +47,8 @@ export function replaceResources(
38
47
return ts . visitEachChild ( node , visitNode , context ) ;
39
48
} ;
40
49
41
- // emit helper for `import Name from "foo"`
42
- // importName is marked as an internal property but is needed for the tslib import.
43
- const importDefaultHelper : ts . UnscopedEmitHelper & { importName ?: string ; } = {
44
- name : 'typescript:commonjsimportdefault' ,
45
- importName : '__importDefault' ,
46
- scoped : false ,
47
- text : tags . stripIndent `
48
- var __importDefault = (this && this.__importDefault) || function (mod) {
49
- return (mod && mod.__esModule) ? mod : { "default": mod };
50
- };` ,
51
- } ;
52
-
53
50
return ( sourceFile : ts . SourceFile ) => {
54
51
if ( shouldTransform ( sourceFile . fileName ) ) {
55
- context . requestEmitHelper ( importDefaultHelper ) ;
56
-
57
52
return ts . visitNode ( sourceFile , visitNode ) ;
58
53
}
59
54
@@ -63,9 +58,11 @@ export function replaceResources(
63
58
}
64
59
65
60
function visitDecorator (
61
+ context : ts . TransformationContext ,
66
62
node : ts . Decorator ,
67
63
typeChecker : ts . TypeChecker ,
68
- directTemplateLoading : boolean ) : ts . Decorator {
64
+ directTemplateLoading : boolean ,
65
+ ) : ts . Decorator {
69
66
if ( ! isComponentDecorator ( node , typeChecker ) ) {
70
67
return node ;
71
68
}
@@ -85,10 +82,8 @@ function visitDecorator(
85
82
const styleReplacements : ts . Expression [ ] = [ ] ;
86
83
87
84
// visit all properties
88
- let properties = ts . visitNodes (
89
- objectExpression . properties ,
90
- ( node : ts . ObjectLiteralElementLike ) =>
91
- visitComponentMetadata ( node , styleReplacements , directTemplateLoading ) ,
85
+ let properties = ts . visitNodes ( objectExpression . properties , ( node : ts . ObjectLiteralElementLike ) =>
86
+ visitComponentMetadata ( context , node , styleReplacements , directTemplateLoading ) ,
92
87
) ;
93
88
94
89
// replace properties with updated properties
@@ -103,16 +98,14 @@ function visitDecorator(
103
98
104
99
return ts . updateDecorator (
105
100
node ,
106
- ts . updateCall (
107
- decoratorFactory ,
108
- decoratorFactory . expression ,
109
- decoratorFactory . typeArguments ,
110
- [ ts . updateObjectLiteral ( objectExpression , properties ) ] ,
111
- ) ,
101
+ ts . updateCall ( decoratorFactory , decoratorFactory . expression , decoratorFactory . typeArguments , [
102
+ ts . updateObjectLiteral ( objectExpression , properties ) ,
103
+ ] ) ,
112
104
) ;
113
105
}
114
106
115
107
function visitComponentMetadata (
108
+ context : ts . TransformationContext ,
116
109
node : ts . ObjectLiteralElementLike ,
117
110
styleReplacements : ts . Expression [ ] ,
118
111
directTemplateLoading : boolean ,
@@ -124,14 +117,17 @@ function visitComponentMetadata(
124
117
const name = node . name . text ;
125
118
switch ( name ) {
126
119
case 'moduleId' :
127
-
128
120
return undefined ;
129
121
130
122
case 'templateUrl' :
131
123
return ts . updatePropertyAssignment (
132
124
node ,
133
125
ts . createIdentifier ( 'template' ) ,
134
- createRequireExpression ( node . initializer , directTemplateLoading ? '!raw-loader!' : '' ) ,
126
+ createRequireExpression (
127
+ context ,
128
+ node . initializer ,
129
+ directTemplateLoading ? '!raw-loader!' : '' ,
130
+ ) ,
135
131
) ;
136
132
137
133
case 'styles' :
@@ -141,16 +137,15 @@ function visitComponentMetadata(
141
137
}
142
138
143
139
const isInlineStyles = name === 'styles' ;
144
- const styles = ts . visitNodes (
145
- node . initializer . elements ,
146
- ( node : ts . Expression ) => {
147
- if ( ! ts . isStringLiteral ( node ) && ! ts . isNoSubstitutionTemplateLiteral ( node ) ) {
148
- return node ;
149
- }
150
-
151
- return isInlineStyles ? ts . createLiteral ( node . text ) : createRequireExpression ( node ) ;
152
- } ,
153
- ) ;
140
+ const styles = ts . visitNodes ( node . initializer . elements , ( node : ts . Expression ) => {
141
+ if ( ! ts . isStringLiteral ( node ) && ! ts . isNoSubstitutionTemplateLiteral ( node ) ) {
142
+ return node ;
143
+ }
144
+
145
+ return isInlineStyles
146
+ ? ts . createLiteral ( node . text )
147
+ : createRequireExpression ( context , node ) ;
148
+ } ) ;
154
149
155
150
// Styles should be placed first
156
151
if ( isInlineStyles ) {
@@ -188,17 +183,21 @@ function isComponentDecorator(node: ts.Node, typeChecker: ts.TypeChecker): node
188
183
return false ;
189
184
}
190
185
191
- function createRequireExpression ( node : ts . Expression , loader ?: string ) : ts . Expression {
186
+ function createRequireExpression (
187
+ context : ts . TransformationContext ,
188
+ node : ts . Expression ,
189
+ loader ?: string ,
190
+ ) : ts . Expression {
192
191
const url = getResourceUrl ( node , loader ) ;
193
192
if ( ! url ) {
194
193
return node ;
195
194
}
196
195
197
- const callExpression = ts . createCall (
198
- ts . createIdentifier ( 'require' ) ,
199
- undefined ,
200
- [ ts . createLiteral ( url ) ] ,
201
- ) ;
196
+ context . requestEmitHelper ( importDefaultHelper ) ;
197
+
198
+ const callExpression = ts . createCall ( ts . createIdentifier ( 'require' ) , undefined , [
199
+ ts . createLiteral ( url ) ,
200
+ ] ) ;
202
201
203
202
return ts . createPropertyAccess (
204
203
ts . createCall (
0 commit comments