Skip to content

Commit d6a32e3

Browse files
authored
Fix import fix on react or react dev (microsoft#41950)
1 parent bb8b9db commit d6a32e3

File tree

4 files changed

+93
-5
lines changed

4 files changed

+93
-5
lines changed

src/services/codefixes/fixCannotFindModule.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ namespace ts.codefix {
4444
}
4545

4646
function tryGetImportedPackageName(sourceFile: SourceFile, pos: number): string | undefined {
47-
const moduleName = cast(getTokenAtPosition(sourceFile, pos), isStringLiteral).text;
47+
const moduleSpecifierText = tryCast(getTokenAtPosition(sourceFile, pos), isStringLiteral);
48+
if (!moduleSpecifierText) return undefined;
49+
const moduleName = moduleSpecifierText.text;
4850
const { packageName } = parsePackageName(moduleName);
4951
return isExternalModuleNameRelative(packageName) ? undefined : packageName;
5052
}

src/services/codefixes/importFixes.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -544,11 +544,11 @@ namespace ts.codefix {
544544

545545
function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): FixesInfo | undefined {
546546
const checker = program.getTypeChecker();
547-
const symbolName = getSymbolName(sourceFile, checker, symbolToken);
547+
const compilerOptions = program.getCompilerOptions();
548+
const symbolName = getSymbolName(sourceFile, checker, symbolToken, compilerOptions);
548549
// "default" is a keyword and not a legal identifier for the import, so we don't expect it here
549550
Debug.assert(symbolName !== InternalSymbolName.Default, "'default' isn't a legal identifier and couldn't occur here");
550551

551-
const compilerOptions = program.getCompilerOptions();
552552
const preferTypeOnlyImport = compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error && isValidTypeOnlyAliasUseSite(symbolToken);
553553
const useRequire = shouldUseRequire(sourceFile, program);
554554
const exportInfos = getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host);
@@ -557,9 +557,9 @@ namespace ts.codefix {
557557
return { fixes, symbolName };
558558
}
559559

560-
function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier): string {
560+
function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string {
561561
const parent = symbolToken.parent;
562-
if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken) {
562+
if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && compilerOptions.jsx !== JsxEmit.ReactJSX && compilerOptions.jsx !== JsxEmit.ReactJSXDev) {
563563
const jsxNamespace = checker.getJsxNamespace(sourceFile);
564564
if (isIntrinsicJsxName(symbolToken.text) || !checker.resolveName(jsxNamespace, parent, SymbolFlags.Value, /*excludeGlobals*/ true)) {
565565
return jsxNamespace;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @jsx: react-jsx
4+
5+
// @Filename: node_modules/react/index.d.ts
6+
////export declare var React: any;
7+
8+
// @Filename: node_modules/react/package.json
9+
////{
10+
//// "name": "react",
11+
//// "types": "./index.d.ts"
12+
////}
13+
14+
// @Filename: foo.tsx
15+
//// export default function Foo(){
16+
//// return <></>;
17+
//// }
18+
19+
// @Filename: bar.tsx
20+
//// export default function Bar(){
21+
//// return <Foo></Foo>;
22+
//// }
23+
24+
// @Filename: package.json
25+
////{
26+
//// "dependencies": {
27+
//// "react": "*"
28+
//// }
29+
////}
30+
31+
goTo.file('bar.tsx')
32+
33+
verify.codeFixAll({
34+
fixId: "fixMissingImport",
35+
fixAllDescription: "Add all missing imports",
36+
newFileContent:
37+
`import Foo from "./foo";
38+
39+
export default function Bar(){
40+
return <Foo></Foo>;
41+
}`,
42+
});
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @jsx: react-jsxdev
4+
5+
// @Filename: node_modules/react/index.d.ts
6+
////export declare var React: any;
7+
8+
// @Filename: node_modules/react/package.json
9+
////{
10+
//// "name": "react",
11+
//// "types": "./index.d.ts"
12+
////}
13+
14+
// @Filename: foo.tsx
15+
//// export default function Foo(){
16+
//// return <></>;
17+
//// }
18+
19+
// @Filename: bar.tsx
20+
//// export default function Bar(){
21+
//// return <Foo></Foo>;
22+
//// }
23+
24+
// @Filename: package.json
25+
////{
26+
//// "dependencies": {
27+
//// "react": "*"
28+
//// }
29+
////}
30+
31+
goTo.file('bar.tsx')
32+
33+
verify.codeFixAll({
34+
fixId: "fixMissingImport",
35+
fixAllDescription: "Add all missing imports",
36+
newFileContent:
37+
`import Foo from "./foo";
38+
39+
export default function Bar(){
40+
return <Foo></Foo>;
41+
}`,
42+
});
43+

0 commit comments

Comments
 (0)