@@ -52,7 +52,7 @@ export function transformOutput(
52
52
}
53
53
opts . outDir = pathLib . join ( outRoot , '/' , locale ) ;
54
54
program . emit ( undefined , undefined , undefined , undefined , {
55
- before : [ litLocalizeTransform ( translations ) ] ,
55
+ before : [ litLocalizeTransform ( translations , program ) ] ,
56
56
} ) ;
57
57
}
58
58
}
@@ -61,10 +61,11 @@ export function transformOutput(
61
61
* Return a TypeScript TransformerFactory for the lit-localize transformer.
62
62
*/
63
63
export function litLocalizeTransform (
64
- translations : Map < string , Message > | undefined
64
+ translations : Map < string , Message > | undefined ,
65
+ program : ts . Program
65
66
) : ts . TransformerFactory < ts . SourceFile > {
66
67
return ( context ) => {
67
- const transformer = new Transformer ( context , translations ) ;
68
+ const transformer = new Transformer ( context , translations , program ) ;
68
69
return ( file ) => ts . visitNode ( file , transformer . boundVisitNode ) ;
69
70
} ;
70
71
}
@@ -75,21 +76,24 @@ export function litLocalizeTransform(
75
76
class Transformer {
76
77
private context : ts . TransformationContext ;
77
78
private translations : Map < string , Message > | undefined ;
79
+ private typeChecker : ts . TypeChecker ;
78
80
boundVisitNode = this . visitNode . bind ( this ) ;
79
81
80
82
constructor (
81
83
context : ts . TransformationContext ,
82
- translations : Map < string , Message > | undefined
84
+ translations : Map < string , Message > | undefined ,
85
+ program : ts . Program
83
86
) {
84
87
this . context = context ;
85
88
this . translations = translations ;
89
+ this . typeChecker = program . getTypeChecker ( ) ;
86
90
}
87
91
88
92
/**
89
93
* Top-level delegating visitor for all nodes.
90
94
*/
91
95
visitNode ( node : ts . Node ) : ts . VisitResult < ts . Node > {
92
- if ( isMsgCall ( node ) ) {
96
+ if ( isMsgCall ( node , this . typeChecker ) ) {
93
97
return this . replaceMsgCall ( node ) ;
94
98
}
95
99
if ( isLitTemplate ( node ) ) {
@@ -101,8 +105,8 @@ class Transformer {
101
105
)
102
106
) ;
103
107
}
104
- if ( ts . isImportDeclaration ( node ) ) {
105
- return this . removeMsgImport ( node ) ;
108
+ if ( this . isLitLocalizeImport ( node ) ) {
109
+ return undefined ;
106
110
}
107
111
return ts . visitEachChild ( node , this . boundVisitNode , this . context ) ;
108
112
}
@@ -329,29 +333,29 @@ class Transformer {
329
333
}
330
334
331
335
/**
332
- * Remove import declarations for the lit-localize `msg` function, because we
333
- * are transforming away all calls to that function.
336
+ * Return whether the given node is an import for the lit-localize module.
334
337
*/
335
- removeMsgImport (
336
- imprt : ts . ImportDeclaration
337
- ) : ts . ImportDeclaration | undefined {
338
- const clause = imprt . importClause ;
339
- if ( clause === undefined ) {
340
- return imprt ;
338
+ isLitLocalizeImport ( node : ts . Node ) : node is ts . ImportDeclaration {
339
+ if ( ! ts . isImportDeclaration ( node ) ) {
340
+ return false ;
341
341
}
342
- const bindings = clause . namedBindings ;
343
- if ( bindings === undefined || ! ts . isNamedImports ( bindings ) ) {
344
- return imprt ;
342
+ const moduleSymbol = this . typeChecker . getSymbolAtLocation (
343
+ node . moduleSpecifier
344
+ ) ;
345
+ if ( ! moduleSymbol || ! moduleSymbol . exports ) {
346
+ return false ;
345
347
}
346
- // TODO(aomarks) This is too crude. We should do better to identify only our
347
- // `msg` function.
348
- if (
349
- bindings . elements . length === 1 &&
350
- bindings . elements [ 0 ] . name . text === 'msg'
351
- ) {
352
- return undefined ;
348
+ const exports = moduleSymbol . exports . values ( ) ;
349
+ for ( const xport of exports as typeof exports & {
350
+ [ Symbol . iterator ] ( ) : Iterator < ts . Symbol > ;
351
+ } ) {
352
+ const type = this . typeChecker . getTypeAtLocation ( xport . valueDeclaration ) ;
353
+ const props = this . typeChecker . getPropertiesOfType ( type ) ;
354
+ if ( props . some ( ( prop ) => prop . escapedName === '_LIT_LOCALIZE_MSG_' ) ) {
355
+ return true ;
356
+ }
353
357
}
354
- return imprt ;
358
+ return false ;
355
359
}
356
360
}
357
361
0 commit comments