@@ -4,7 +4,7 @@ namespace ts {
44 interface PerFileState {
55 importSpecifier ?: string ;
66 filenameDeclaration ?: VariableDeclaration & { name : Identifier ; } ;
7- utilizedImplicitRuntimeImports ?: Map < ImportSpecifier > ;
7+ utilizedImplicitRuntimeImports ?: Map < Map < ImportSpecifier > > ;
88 }
99
1010 const {
@@ -40,17 +40,25 @@ namespace ts {
4040 }
4141
4242 function getImplicitImportForName ( name : string ) {
43- const existing = currentFileState . utilizedImplicitRuntimeImports ?. get ( name ) ;
43+ const importSource = name === "createElement"
44+ ? currentFileState . importSpecifier !
45+ : `${ currentFileState . importSpecifier } /${ compilerOptions . jsx === JsxEmit . ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime" } ` ;
46+ const existing = currentFileState . utilizedImplicitRuntimeImports ?. get ( importSource ) ?. get ( name ) ;
4447 if ( existing ) {
4548 return existing . name ;
4649 }
4750 if ( ! currentFileState . utilizedImplicitRuntimeImports ) {
4851 currentFileState . utilizedImplicitRuntimeImports = createMap ( ) ;
4952 }
53+ let specifierSourceImports = currentFileState . utilizedImplicitRuntimeImports . get ( importSource ) ;
54+ if ( ! specifierSourceImports ) {
55+ specifierSourceImports = createMap ( ) ;
56+ currentFileState . utilizedImplicitRuntimeImports . set ( importSource , specifierSourceImports ) ;
57+ }
5058 const generatedName = factory . createUniqueName ( `_${ name } ` , GeneratedIdentifierFlags . Optimistic | GeneratedIdentifierFlags . FileLevel | GeneratedIdentifierFlags . AllowNameSubstitution ) ;
5159 const specifier = factory . createImportSpecifier ( factory . createIdentifier ( name ) , generatedName ) ;
5260 generatedName . generatedImportReference = specifier ;
53- currentFileState . utilizedImplicitRuntimeImports . set ( name , specifier ) ;
61+ specifierSourceImports . set ( name , specifier ) ;
5462 return generatedName ;
5563 }
5664
@@ -73,29 +81,30 @@ namespace ts {
7381 if ( currentFileState . filenameDeclaration ) {
7482 statements = insertStatementAfterCustomPrologue ( statements . slice ( ) , factory . createVariableStatement ( /*modifiers*/ undefined , factory . createVariableDeclarationList ( [ currentFileState . filenameDeclaration ] , NodeFlags . Const ) ) ) ;
7583 }
76- if ( currentFileState . utilizedImplicitRuntimeImports && currentFileState . utilizedImplicitRuntimeImports . size && currentFileState . importSpecifier !== undefined ) {
77- const specifier = `${ currentFileState . importSpecifier } /${ compilerOptions . jsx === JsxEmit . ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime" } ` ;
78- if ( isExternalModule ( node ) ) {
79- // Add `import` statement
80- const importStatement = factory . createImportDeclaration ( /*decorators*/ undefined , /*modifiers*/ undefined , factory . createImportClause ( /*typeOnly*/ false , /*name*/ undefined , factory . createNamedImports ( arrayFrom ( currentFileState . utilizedImplicitRuntimeImports . values ( ) ) ) ) , factory . createStringLiteral ( specifier ) ) ;
81- setParentRecursive ( importStatement , /*incremental*/ false ) ;
82- statements = insertStatementAfterCustomPrologue ( statements . slice ( ) , importStatement ) ;
83- }
84- else if ( isExternalOrCommonJsModule ( node ) ) {
85- // Add `require` statement
86- const requireStatement = factory . createVariableStatement ( /*modifiers*/ undefined , factory . createVariableDeclarationList ( [
87- factory . createVariableDeclaration (
88- factory . createObjectBindingPattern ( map ( arrayFrom ( currentFileState . utilizedImplicitRuntimeImports . values ( ) ) , s => factory . createBindingElement ( /*dotdotdot*/ undefined , s . propertyName , s . name ) ) ) ,
89- /*exclaimationToken*/ undefined ,
90- /*type*/ undefined ,
91- factory . createCallExpression ( factory . createIdentifier ( "require" ) , /*typeArguments*/ undefined , [ factory . createStringLiteral ( specifier ) ] )
92- )
93- ] , NodeFlags . Const ) ) ;
94- setParentRecursive ( requireStatement , /*incremental*/ false ) ;
95- statements = insertStatementAfterCustomPrologue ( statements . slice ( ) , requireStatement ) ;
96- }
97- else {
98- // Do nothing (script file) - consider an error in the checker?
84+ if ( currentFileState . utilizedImplicitRuntimeImports ) {
85+ for ( const [ importSource , importSpecifiersMap ] of arrayFrom ( currentFileState . utilizedImplicitRuntimeImports . entries ( ) ) ) {
86+ if ( isExternalModule ( node ) ) {
87+ // Add `import` statement
88+ const importStatement = factory . createImportDeclaration ( /*decorators*/ undefined , /*modifiers*/ undefined , factory . createImportClause ( /*typeOnly*/ false , /*name*/ undefined , factory . createNamedImports ( arrayFrom ( importSpecifiersMap . values ( ) ) ) ) , factory . createStringLiteral ( importSource ) ) ;
89+ setParentRecursive ( importStatement , /*incremental*/ false ) ;
90+ statements = insertStatementAfterCustomPrologue ( statements . slice ( ) , importStatement ) ;
91+ }
92+ else if ( isExternalOrCommonJsModule ( node ) ) {
93+ // Add `require` statement
94+ const requireStatement = factory . createVariableStatement ( /*modifiers*/ undefined , factory . createVariableDeclarationList ( [
95+ factory . createVariableDeclaration (
96+ factory . createObjectBindingPattern ( map ( arrayFrom ( importSpecifiersMap . values ( ) ) , s => factory . createBindingElement ( /*dotdotdot*/ undefined , s . propertyName , s . name ) ) ) ,
97+ /*exclaimationToken*/ undefined ,
98+ /*type*/ undefined ,
99+ factory . createCallExpression ( factory . createIdentifier ( "require" ) , /*typeArguments*/ undefined , [ factory . createStringLiteral ( importSource ) ] )
100+ )
101+ ] , NodeFlags . Const ) ) ;
102+ setParentRecursive ( requireStatement , /*incremental*/ false ) ;
103+ statements = insertStatementAfterCustomPrologue ( statements . slice ( ) , requireStatement ) ;
104+ }
105+ else {
106+ // Do nothing (script file) - consider an error in the checker?
107+ }
99108 }
100109 }
101110 if ( statements !== visited . statements ) {
@@ -306,14 +315,21 @@ namespace ts {
306315 }
307316 }
308317
318+ const callee = currentFileState . importSpecifier === undefined
319+ ? createJsxFactoryExpression (
320+ factory ,
321+ context . getEmitResolver ( ) . getJsxFactoryEntity ( currentSourceFile ) ,
322+ compilerOptions . reactNamespace ! , // TODO: GH#18217
323+ node
324+ )
325+ : getImplicitImportForName ( "createElement" ) ;
326+
309327 const element = createExpressionForJsxElement (
310328 factory ,
311- context . getEmitResolver ( ) . getJsxFactoryEntity ( currentSourceFile ) ,
312- compilerOptions . reactNamespace ! , // TODO: GH#18217
329+ callee ,
313330 tagName ,
314331 objectProperties ,
315332 mapDefined ( children , transformJsxChildToExpression ) ,
316- node ,
317333 location
318334 ) ;
319335
0 commit comments