@@ -44,6 +44,7 @@ interface SymbolInfo {
4444 bindings : t . Identifier [ ]
4545 params : GroupedTypeParams
4646 deps : Dep [ ]
47+ children : t . Node [ ]
4748}
4849
4950type NamespaceMap = Map <
@@ -204,8 +205,11 @@ export function createFakeJsPlugin({
204205 }
205206
206207 const params : GroupedTypeParams = collectParams ( decl )
207-
208- const deps = collectDependencies ( decl , namespaceStmts )
208+ const children = new Set < t . Node > ( )
209+ const deps = collectDependencies ( decl , namespaceStmts , children )
210+ const childrenArray = Array . from ( children ) . filter ( ( child ) =>
211+ bindings . every ( ( b ) => child !== b ) ,
212+ )
209213
210214 if ( decl !== stmt ) {
211215 decl . leadingComments = stmt . leadingComments
@@ -216,23 +220,41 @@ export function createFakeJsPlugin({
216220 deps,
217221 bindings,
218222 params,
223+ children : childrenArray ,
219224 } )
220225
221226 const symbolIdNode = t . numericLiteral ( symbolId )
222227 const depsNode = t . arrowFunctionExpression (
223228 params . map ( ( { name } ) => t . identifier ( name ) ) ,
224229 t . arrayExpression ( deps ) ,
225230 )
231+ const interfaceKeysNode = t . arrayExpression (
232+ childrenArray . map ( ( node ) => ( {
233+ type : 'StringLiteral' ,
234+ value : '' ,
235+ start : node . start ,
236+ end : node . end ,
237+ loc : node . loc ,
238+ } ) ) ,
239+ )
226240 const sideEffectNode =
227241 sideEffect &&
228242 t . callExpression ( t . identifier ( 'sideEffect' ) , [ bindings [ 0 ] ] )
229- const runtimeArrayNode = runtimeBindingArrayExpression (
230- sideEffectNode
231- ? [ symbolIdNode , depsNode , sideEffectNode ]
232- : [ symbolIdNode , depsNode ] ,
233- )
234-
235- // var ${binding} = [${symbolId}, (param, ...) => [dep, ...], sideEffect()]
243+ const runtimeArrayNode = runtimeBindingArrayExpression ( [
244+ symbolIdNode ,
245+ depsNode ,
246+ interfaceKeysNode ,
247+ ...( sideEffectNode ? ( [ sideEffectNode ] as const ) : ( [ ] as const ) ) ,
248+ ] )
249+
250+ /*
251+ var ${binding} = [
252+ ${symbolId},
253+ (param, ...) => [dep, ...],
254+ ["interface keys"],
255+ sideEffect()
256+ ]
257+ */
236258 const runtimeAssignment : RuntimeBindingVariableDeclration = {
237259 type : 'VariableDeclaration' ,
238260 kind : 'var' ,
@@ -286,6 +308,7 @@ export function createFakeJsPlugin({
286308 sourceMaps : sourcemap ,
287309 sourceFileName : id ,
288310 } )
311+
289312 return result
290313 }
291314
@@ -324,7 +347,7 @@ export function createFakeJsPlugin({
324347 return null
325348 }
326349
327- const [ symbolIdNode , depsFn /*, ignore sideEffect */ ] =
350+ const [ symbolIdNode , depsFn , children /*, ignore sideEffect */ ] =
328351 node . declarations [ 0 ] . init . elements
329352
330353 const symbolId = symbolIdNode . value
@@ -344,8 +367,17 @@ export function createFakeJsPlugin({
344367 overwriteNode ( original . bindings [ i ] , transformedBinding )
345368 }
346369
347- const transformedParams = depsFn . params as t . Identifier [ ]
370+ for ( const [ i , child ] of (
371+ children . elements as t . StringLiteral [ ]
372+ ) . entries ( ) ) {
373+ Object . assign ( original . children [ i ] , {
374+ loc : child . loc ,
375+ start : child . start ,
376+ end : child . end ,
377+ } )
378+ }
348379
380+ const transformedParams = depsFn . params as t . Identifier [ ]
349381 for ( const [ i , transformedParam ] of transformedParams . entries ( ) ) {
350382 const transformedName = transformedParam . name
351383 for ( const originalTypeParam of original . params [ i ] . typeParams ) {
@@ -459,6 +491,7 @@ export function createFakeJsPlugin({
459491 function collectDependencies (
460492 node : t . Node ,
461493 namespaceStmts : NamespaceMap ,
494+ children : Set < t . Node > ,
462495 ) : Dep [ ] {
463496 const deps = new Set < Dep > ( )
464497 const seen = new Set < t . Node > ( )
@@ -551,10 +584,13 @@ export function createFakeJsPlugin({
551584 namespaceStmts ,
552585 )
553586 addDependency ( dep )
554-
555587 break
556588 }
557589 }
590+
591+ if ( parent && ! deps . has ( node as any ) && isChildSymbol ( node , parent ) ) {
592+ children . add ( node )
593+ }
558594 } ,
559595 } )
560596 return Array . from ( deps )
@@ -610,6 +646,17 @@ export function createFakeJsPlugin({
610646 }
611647}
612648
649+ function isChildSymbol ( node : t . Node , parent : t . Node ) {
650+ if ( node . type === 'Identifier' ) return true
651+ if (
652+ isTypeOf ( parent , [ 'TSPropertySignature' , 'TSMethodSignature' ] ) &&
653+ parent . key === node
654+ )
655+ return true
656+
657+ return false
658+ }
659+
613660function collectInferredNames ( node : t . Node ) {
614661 const inferred : string [ ] = [ ]
615662 walkAST ( node , {
@@ -701,27 +748,30 @@ function runtimeBindingArrayExpression(
701748 return t . arrayExpression ( elements ) as RuntimeBindingArrayExpression
702749}
703750
751+ type RuntimeBindingArrayElementsBase = [
752+ symbolId : t . NumericLiteral ,
753+ deps : t . ArrowFunctionExpression ,
754+ children : t . ArrayExpression ,
755+ ]
756+
704757/**
705758 * An array that represents the elements in {@link RuntimeBindingArrayExpression}
706759 */
707760type RuntimeBindingArrayElements =
708- | [ symbolId : t . NumericLiteral , deps : t . ArrowFunctionExpression ]
709- | [
710- symbolId : t . NumericLiteral ,
711- deps : t . ArrowFunctionExpression ,
712- effect : t . CallExpression ,
713- ]
761+ | RuntimeBindingArrayElementsBase
762+ | [ ...RuntimeBindingArrayElementsBase , effect : t . CallExpression ]
714763
715764/**
716765 * Check if the given array is a {@link RuntimeBindingArrayElements}
717766 */
718767function isRuntimeBindingArrayElements (
719768 elements : Array < t . Node | null | undefined > ,
720769) : elements is RuntimeBindingArrayElements {
721- const [ symbolId , deps , effect ] = elements
770+ const [ symbolId , deps , children , effect ] = elements
722771 return (
723772 t . isNumericLiteral ( symbolId ) &&
724773 t . isArrowFunctionExpression ( deps ) &&
774+ t . isArrayExpression ( children ) &&
725775 ( ! effect || t . isCallExpression ( effect ) )
726776 )
727777}
0 commit comments