diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 482480d8420..c2cb825b5e0 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -44,7 +44,9 @@ namespace ts.codefix { } function tryGetImportedPackageName(sourceFile: SourceFile, pos: number): string | undefined { - const moduleName = cast(getTokenAtPosition(sourceFile, pos), isStringLiteral).text; + const moduleSpecifierText = tryCast(getTokenAtPosition(sourceFile, pos), isStringLiteral); + if (!moduleSpecifierText) return undefined; + const moduleName = moduleSpecifierText.text; const { packageName } = parsePackageName(moduleName); return isExternalModuleNameRelative(packageName) ? undefined : packageName; } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 9700e6b583b..83e22db2241 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -544,11 +544,11 @@ namespace ts.codefix { function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): FixesInfo | undefined { const checker = program.getTypeChecker(); - const symbolName = getSymbolName(sourceFile, checker, symbolToken); + const compilerOptions = program.getCompilerOptions(); + const symbolName = getSymbolName(sourceFile, checker, symbolToken, compilerOptions); // "default" is a keyword and not a legal identifier for the import, so we don't expect it here Debug.assert(symbolName !== InternalSymbolName.Default, "'default' isn't a legal identifier and couldn't occur here"); - const compilerOptions = program.getCompilerOptions(); const preferTypeOnlyImport = compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error && isValidTypeOnlyAliasUseSite(symbolToken); const useRequire = shouldUseRequire(sourceFile, program); const exportInfos = getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host); @@ -557,9 +557,9 @@ namespace ts.codefix { return { fixes, symbolName }; } - function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier): string { + function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string { const parent = symbolToken.parent; - if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken) { + if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && compilerOptions.jsx !== JsxEmit.ReactJSX && compilerOptions.jsx !== JsxEmit.ReactJSXDev) { const jsxNamespace = checker.getJsxNamespace(sourceFile); if (isIntrinsicJsxName(symbolToken.text) || !checker.resolveName(jsxNamespace, parent, SymbolFlags.Value, /*excludeGlobals*/ true)) { return jsxNamespace; diff --git a/tests/cases/fourslash/codeFixAddMissingImportForReactJsx1.ts b/tests/cases/fourslash/codeFixAddMissingImportForReactJsx1.ts new file mode 100644 index 00000000000..765131d5a6e --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingImportForReactJsx1.ts @@ -0,0 +1,43 @@ +/// + +// @jsx: react-jsx + +// @Filename: node_modules/react/index.d.ts +////export declare var React: any; + +// @Filename: node_modules/react/package.json +////{ +//// "name": "react", +//// "types": "./index.d.ts" +////} + +// @Filename: foo.tsx +//// export default function Foo(){ +//// return <>; +//// } + +// @Filename: bar.tsx +//// export default function Bar(){ +//// return ; +//// } + +// @Filename: package.json +////{ +//// "dependencies": { +//// "react": "*" +//// } +////} + +goTo.file('bar.tsx') + +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: +`import Foo from "./foo"; + +export default function Bar(){ + return ; +}`, +}); + diff --git a/tests/cases/fourslash/codeFixAddMissingImportForReactJsx2.ts b/tests/cases/fourslash/codeFixAddMissingImportForReactJsx2.ts new file mode 100644 index 00000000000..8a7ae5669f2 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingImportForReactJsx2.ts @@ -0,0 +1,43 @@ +/// + +// @jsx: react-jsxdev + +// @Filename: node_modules/react/index.d.ts +////export declare var React: any; + +// @Filename: node_modules/react/package.json +////{ +//// "name": "react", +//// "types": "./index.d.ts" +////} + +// @Filename: foo.tsx +//// export default function Foo(){ +//// return <>; +//// } + +// @Filename: bar.tsx +//// export default function Bar(){ +//// return ; +//// } + +// @Filename: package.json +////{ +//// "dependencies": { +//// "react": "*" +//// } +////} + +goTo.file('bar.tsx') + +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: +`import Foo from "./foo"; + +export default function Bar(){ + return ; +}`, +}); +