mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-23 10:04:47 -05:00
fix(33511): show jsx namespace default import quick fix if it does not exists in the current scope (#38419)
This commit is contained in:
@@ -491,12 +491,7 @@ namespace ts.codefix {
|
||||
|
||||
function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): FixesInfo | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
// If we're at `<Foo/>`, we must check if `Foo` is already in scope, and if so, get an import for `React` instead.
|
||||
const symbolName = isJsxOpeningLikeElement(symbolToken.parent)
|
||||
&& symbolToken.parent.tagName === symbolToken
|
||||
&& (isIntrinsicJsxName(symbolToken.text) || checker.resolveName(symbolToken.text, symbolToken, SymbolFlags.All, /*excludeGlobals*/ false))
|
||||
? checker.getJsxNamespace(sourceFile)
|
||||
: symbolToken.text;
|
||||
const symbolName = getSymbolName(sourceFile, checker, symbolToken);
|
||||
// "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");
|
||||
|
||||
@@ -509,6 +504,17 @@ namespace ts.codefix {
|
||||
return { fixes, symbolName };
|
||||
}
|
||||
|
||||
function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier): string {
|
||||
const parent = symbolToken.parent;
|
||||
if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken) {
|
||||
const jsxNamespace = checker.getJsxNamespace(sourceFile);
|
||||
if (isIntrinsicJsxName(symbolToken.text) || !checker.resolveName(jsxNamespace, parent, SymbolFlags.Value, /*excludeGlobals*/ true)) {
|
||||
return jsxNamespace;
|
||||
}
|
||||
}
|
||||
return symbolToken.text;
|
||||
}
|
||||
|
||||
// Returns a map from an exported symbol's ID to a list of every way it's (re-)exported.
|
||||
function getExportInfos(
|
||||
symbolName: string,
|
||||
|
||||
31
tests/cases/fourslash/importNameCodeFix_jsx2.ts
Normal file
31
tests/cases/fourslash/importNameCodeFix_jsx2.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////export = React;
|
||||
////export as namespace React;
|
||||
////declare namespace React {
|
||||
//// class Component {}
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/react-native/index.d.ts
|
||||
////import * as React from "react";
|
||||
////export class Text extends React.Component {};
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////import React from "react";
|
||||
////<[|Text|]></Text>;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"],
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
import { Text } from "react-native";
|
||||
<Text></Text>;`
|
||||
});
|
||||
31
tests/cases/fourslash/importNameCodeFix_jsx3.ts
Normal file
31
tests/cases/fourslash/importNameCodeFix_jsx3.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////export = React;
|
||||
////export as namespace React;
|
||||
////declare namespace React {
|
||||
//// class Component {}
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/react-native/index.d.ts
|
||||
////import * as React from "react";
|
||||
////export class Text extends React.Component {};
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////import React from "react";
|
||||
////<Text></[|Text|]>;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"],
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
import { Text } from "react-native";
|
||||
<Text></Text>;`
|
||||
});
|
||||
31
tests/cases/fourslash/importNameCodeFix_jsx4.ts
Normal file
31
tests/cases/fourslash/importNameCodeFix_jsx4.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////export = React;
|
||||
////export as namespace React;
|
||||
////declare namespace React {
|
||||
//// class Component {}
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/react-native/index.d.ts
|
||||
////import * as React from "react";
|
||||
////export class Text extends React.Component {};
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////import { Text } from "react-native";
|
||||
////<Text></Text>;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_default_0_from_module_1.message, "React", "react"],
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
import { Text } from "react-native";
|
||||
<Text></Text>;`
|
||||
});
|
||||
31
tests/cases/fourslash/importNameCodeFix_jsx5.ts
Normal file
31
tests/cases/fourslash/importNameCodeFix_jsx5.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////export = React;
|
||||
////export as namespace React;
|
||||
////declare namespace React {
|
||||
//// class Component {}
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/react-native/index.d.ts
|
||||
////import * as React from "react";
|
||||
////export class Text extends React.Component {};
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////import React from "react";
|
||||
////<[|Text|] />;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"],
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
import { Text } from "react-native";
|
||||
<Text />;`
|
||||
});
|
||||
41
tests/cases/fourslash/importNameCodeFix_jsx6.ts
Normal file
41
tests/cases/fourslash/importNameCodeFix_jsx6.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////export = React;
|
||||
////export as namespace React;
|
||||
////declare namespace React {
|
||||
//// class Component {}
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/react-native/index.d.ts
|
||||
////import * as React from "react";
|
||||
////export class Text extends React.Component {};
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////<[|Text|]></Text>;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_default_0_from_module_1.message, "React", "react"],
|
||||
applyChanges: true,
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
|
||||
<Text></Text>;`
|
||||
});
|
||||
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"],
|
||||
newFileContent:
|
||||
`import React from "react";
|
||||
import { Text } from "react-native";
|
||||
|
||||
<Text></Text>;`
|
||||
});
|
||||
15
tests/cases/fourslash/importNameCodeFix_jsx7.ts
Normal file
15
tests/cases/fourslash/importNameCodeFix_jsx7.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @jsx: react
|
||||
// @module: esnext
|
||||
// @esModuleInterop: true
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: /node_modules/react/index.d.ts
|
||||
////// React was not defined
|
||||
|
||||
// @Filename: /a.tsx
|
||||
////<[|Text|]></Text>;
|
||||
|
||||
goTo.file("/a.tsx");
|
||||
verify.not.codeFixAvailable();
|
||||
Reference in New Issue
Block a user