@@ -460,6 +460,12 @@ namespace ts.refactor {
460460 const oldImportsNeededByNewFile = new SymbolSet ( ) ;
461461 const newFileImportsFromOldFile = new SymbolSet ( ) ;
462462
463+ const containsJsx = find ( toMove , statement => ! ! ( statement . transformFlags & TransformFlags . ContainsJsx ) ) ;
464+ const jsxNamespaceSymbol = getJsxNamespaceSymbol ( containsJsx ) ;
465+ if ( jsxNamespaceSymbol ) { // Might not exist (e.g. in non-compiling code)
466+ oldImportsNeededByNewFile . add ( jsxNamespaceSymbol ) ;
467+ }
468+
463469 for ( const statement of toMove ) {
464470 forEachTopLevelDeclaration ( statement , decl => {
465471 movedSymbols . add ( Debug . assertDefined ( isExpressionStatement ( decl ) ? checker . getSymbolAtLocation ( decl . expression . left ) : decl . symbol ) ) ;
@@ -485,13 +491,35 @@ namespace ts.refactor {
485491 for ( const statement of oldFile . statements ) {
486492 if ( contains ( toMove , statement ) ) continue ;
487493
494+ // jsxNamespaceSymbol will only be set iff it is in oldImportsNeededByNewFile.
495+ if ( jsxNamespaceSymbol && ! ! ( statement . transformFlags & TransformFlags . ContainsJsx ) ) {
496+ unusedImportsFromOldFile . delete ( jsxNamespaceSymbol ) ;
497+ }
498+
488499 forEachReference ( statement , checker , symbol => {
489500 if ( movedSymbols . has ( symbol ) ) oldFileImportsFromNewFile . add ( symbol ) ;
490501 unusedImportsFromOldFile . delete ( symbol ) ;
491502 } ) ;
492503 }
493504
494505 return { movedSymbols, newFileImportsFromOldFile, oldFileImportsFromNewFile, oldImportsNeededByNewFile, unusedImportsFromOldFile } ;
506+
507+ function getJsxNamespaceSymbol ( containsJsx : Node | undefined ) {
508+ if ( containsJsx === undefined ) {
509+ return undefined ;
510+ }
511+
512+ const jsxNamespace = checker . getJsxNamespace ( containsJsx ) ;
513+
514+ // Strictly speaking, this could resolve to a symbol other than the JSX namespace.
515+ // This will produce erroneous output (probably, an incorrectly copied import) but
516+ // is expected to be very rare and easily reversible.
517+ const jsxNamespaceSymbol = checker . resolveName ( jsxNamespace , containsJsx , SymbolFlags . Namespace , /*excludeGlobals*/ true ) ;
518+
519+ return ! ! jsxNamespaceSymbol && some ( jsxNamespaceSymbol . declarations , isInImport )
520+ ? jsxNamespaceSymbol
521+ : undefined ;
522+ }
495523 }
496524
497525 // Below should all be utilities
@@ -512,7 +540,7 @@ namespace ts.refactor {
512540 }
513541 function isVariableDeclarationInImport ( decl : VariableDeclaration ) {
514542 return isSourceFile ( decl . parent . parent . parent ) &&
515- decl . initializer && isRequireCall ( decl . initializer , /*checkArgumentIsStringLiteralLike*/ true ) ;
543+ ! ! decl . initializer && isRequireCall ( decl . initializer , /*checkArgumentIsStringLiteralLike*/ true ) ;
516544 }
517545
518546 function filterImport ( i : SupportedImport , moduleSpecifier : StringLiteralLike , keep : ( name : Identifier ) => boolean ) : SupportedImportStatement | undefined {
0 commit comments