fix(41194): ignore jsxFrag identifier in import declarations (#41441)

This commit is contained in:
Oleksandr T
2020-11-25 00:29:47 +02:00
committed by GitHub
parent d070acf29d
commit 03877260f8
5 changed files with 39 additions and 1 deletions

View File

@@ -646,6 +646,10 @@ namespace ts {
return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals);
},
getJsxNamespace: n => unescapeLeadingUnderscores(getJsxNamespace(n)),
getJsxFragmentFactory: n => {
const jsxFragmentFactory = getJsxFragmentFactoryEntity(n);
return jsxFragmentFactory && unescapeLeadingUnderscores(getFirstIdentifier(jsxFragmentFactory).escapedText);
},
getAccessibleSymbolChain,
getTypePredicateOfSignature,
resolveExternalModuleName: moduleSpecifierIn => {

View File

@@ -4131,6 +4131,7 @@ namespace ts {
/* @internal */ getAllPossiblePropertiesOfTypes(type: readonly Type[]): Symbol[];
/* @internal */ resolveName(name: string, location: Node | undefined, meaning: SymbolFlags, excludeGlobals: boolean): Symbol | undefined;
/* @internal */ getJsxNamespace(location?: Node): string;
/* @internal */ getJsxFragmentFactory(location: Node): string | undefined;
/**
* Note that this will return undefined in the following case:

View File

@@ -86,6 +86,7 @@ namespace ts.OrganizeImports {
function removeUnusedImports(oldImports: readonly ImportDeclaration[], sourceFile: SourceFile, program: Program) {
const typeChecker = program.getTypeChecker();
const jsxNamespace = typeChecker.getJsxNamespace(sourceFile);
const jsxFragmentFactory = typeChecker.getJsxFragmentFactory(sourceFile);
const jsxElementsPresent = !!(sourceFile.transformFlags & TransformFlags.ContainsJsx);
const usedImports: ImportDeclaration[] = [];
@@ -150,7 +151,8 @@ namespace ts.OrganizeImports {
function isDeclarationUsed(identifier: Identifier) {
// The JSX factory symbol is always used if JSX elements are present - even if they are not allowed.
return jsxElementsPresent && (identifier.text === jsxNamespace) || FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
return jsxElementsPresent && (identifier.text === jsxNamespace || jsxFragmentFactory && identifier.text === jsxFragmentFactory) ||
FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
}
}

View File

@@ -757,6 +757,24 @@ export namespace React {
}
);
testOrganizeImports("JsxFragmentPragmaTsx",
{
path: "/test.tsx",
content: `/** @jsx h */
/** @jsxFrag frag */
import { h, frag } from "@foo/core";
const elem = <><div>Foo</div></>;
`,
},
{
path: "/@foo/core/index.d.ts",
content: `export function h(): void;
export function frag(): void;
`
}
);
describe("Exports", () => {
testOrganizeExports("MoveToTop",

View File

@@ -0,0 +1,13 @@
// ==ORIGINAL==
/** @jsx h */
/** @jsxFrag frag */
import { h, frag } from "@foo/core";
const elem = <><div>Foo</div></>;
// ==ORGANIZED==
/** @jsx h */
/** @jsxFrag frag */
import { frag, h } from "@foo/core";
const elem = <><div>Foo</div></>;