@@ -180,7 +180,7 @@ namespace ts.codefix {
180180 export const enum ImportKind {
181181 Named ,
182182 Default ,
183- Namespace ,
183+ Namespace
184184 }
185185
186186 export function getCodeActionForImport ( moduleSymbol : Symbol , context : ImportCodeFixOptions ) : ImportCodeAction [ ] {
@@ -212,7 +212,7 @@ namespace ts.codefix {
212212
213213 function getNamespaceImportName ( declaration : AnyImportSyntax ) : Identifier {
214214 if ( declaration . kind === SyntaxKind . ImportDeclaration ) {
215- const namedBindings = declaration . importClause && declaration . importClause . namedBindings ;
215+ const namedBindings = declaration . importClause && isImportClause ( declaration . importClause ) && declaration . importClause . namedBindings ;
216216 return namedBindings && namedBindings . kind === SyntaxKind . NamespaceImport ? namedBindings . name : undefined ;
217217 }
218218 else {
@@ -237,6 +237,8 @@ namespace ts.codefix {
237237 return parent as ImportDeclaration ;
238238 case SyntaxKind . ExternalModuleReference :
239239 return ( parent as ExternalModuleReference ) . parent ;
240+ case SyntaxKind . ImportEqualsDeclaration :
241+ return parent as ImportEqualsDeclaration ;
240242 default :
241243 Debug . assert ( parent . kind === SyntaxKind . ExportDeclaration ) ;
242244 // Ignore these, can't add imports to them.
@@ -249,11 +251,13 @@ namespace ts.codefix {
249251 const lastImportDeclaration = findLast ( sourceFile . statements , isAnyImportSyntax ) ;
250252
251253 const moduleSpecifierWithoutQuotes = stripQuotes ( moduleSpecifier ) ;
254+ const quotedModuleSpecifier = createStringLiteralWithQuoteStyle ( sourceFile , moduleSpecifierWithoutQuotes ) ;
252255 const importDecl = createImportDeclaration (
253- /*decorators*/ undefined ,
254- /*modifiers*/ undefined ,
256+ /*decorators*/ undefined ,
257+ /*modifiers*/ undefined ,
255258 createImportClauseOfKind ( kind , symbolName ) ,
256- createStringLiteralWithQuoteStyle ( sourceFile , moduleSpecifierWithoutQuotes ) ) ;
259+ quotedModuleSpecifier ) ;
260+
257261 const changes = ChangeTracker . with ( context , changeTracker => {
258262 if ( lastImportDeclaration ) {
259263 changeTracker . insertNodeAfter ( sourceFile , lastImportDeclaration , importDecl , { suffix : newLineCharacter } ) ;
@@ -263,11 +267,15 @@ namespace ts.codefix {
263267 }
264268 } ) ;
265269
270+ const actionFormat = kind === ImportKind . Namespace
271+ ? Diagnostics . Import_Asterisk_as_0_from_1
272+ : Diagnostics . Import_0_from_1 ;
273+
266274 // if this file doesn't have any import statements, insert an import statement and then insert a new line
267275 // between the only import statement and user code. Otherwise just insert the statement because chances
268276 // are there are already a new line seperating code and import statements.
269277 return createCodeAction (
270- Diagnostics . Import_0_from_1 ,
278+ actionFormat ,
271279 [ symbolName , moduleSpecifierWithoutQuotes ] ,
272280 changes ,
273281 "NewImport" ,
@@ -282,7 +290,7 @@ namespace ts.codefix {
282290 return literal ;
283291 }
284292
285- function createImportClauseOfKind ( kind : ImportKind , symbolName : string ) {
293+ function createImportClauseOfKind ( kind : ImportKind . Default | ImportKind . Named | ImportKind . Namespace , symbolName : string ) {
286294 const id = createIdentifier ( symbolName ) ;
287295 switch ( kind ) {
288296 case ImportKind . Default :
@@ -534,7 +542,7 @@ namespace ts.codefix {
534542 declarations : ReadonlyArray < AnyImportSyntax > ) : ImportCodeAction {
535543 const fromExistingImport = firstDefined ( declarations , declaration => {
536544 if ( declaration . kind === SyntaxKind . ImportDeclaration && declaration . importClause ) {
537- const changes = tryUpdateExistingImport ( ctx , declaration . importClause ) ;
545+ const changes = tryUpdateExistingImport ( ctx , isImportClause ( declaration . importClause ) && declaration . importClause || undefined ) ;
538546 if ( changes ) {
539547 const moduleSpecifierWithoutQuotes = stripQuotes ( declaration . moduleSpecifier . getText ( ) ) ;
540548 return createCodeAction (
@@ -564,9 +572,10 @@ namespace ts.codefix {
564572 return expression && isStringLiteral ( expression ) ? expression . text : undefined ;
565573 }
566574
567- function tryUpdateExistingImport ( context : SymbolContext & { kind : ImportKind } , importClause : ImportClause ) : FileTextChanges [ ] | undefined {
575+ function tryUpdateExistingImport ( context : SymbolContext & { kind : ImportKind } , importClause : ImportClause | ImportEqualsDeclaration ) : FileTextChanges [ ] | undefined {
568576 const { symbolName, sourceFile, kind } = context ;
569- const { name, namedBindings } = importClause ;
577+ const { name } = importClause ;
578+ const { namedBindings } = importClause . kind !== SyntaxKind . ImportEqualsDeclaration && importClause ;
570579 switch ( kind ) {
571580 case ImportKind . Default :
572581 return name ? undefined : ChangeTracker . with ( context , t =>
@@ -627,7 +636,7 @@ namespace ts.codefix {
627636 }
628637
629638 function getActionsForUMDImport ( context : ImportCodeFixContext ) : ImportCodeAction [ ] {
630- const { checker, symbolToken } = context ;
639+ const { checker, symbolToken, compilerOptions } = context ;
631640 const umdSymbol = checker . getSymbolAtLocation ( symbolToken ) ;
632641 let symbol : ts . Symbol ;
633642 let symbolName : string ;
@@ -644,6 +653,14 @@ namespace ts.codefix {
644653 Debug . fail ( "Either the symbol or the JSX namespace should be a UMD global if we got here" ) ;
645654 }
646655
656+ const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports ( compilerOptions ) ;
657+
658+ // Import a synthetic `default` if enabled.
659+ if ( allowSyntheticDefaultImports ) {
660+ return getCodeActionForImport ( symbol , { ...context , symbolName, kind : ImportKind . Default } ) ;
661+ }
662+
663+ // Fall back to the `import * as ns` style import.
647664 return getCodeActionForImport ( symbol , { ...context , symbolName, kind : ImportKind . Namespace } ) ;
648665 }
649666
0 commit comments