From 03877260f8f2f597e8c451f317992417076150d1 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 25 Nov 2020 00:29:47 +0200 Subject: [PATCH] fix(41194): ignore jsxFrag identifier in import declarations (#41441) --- src/compiler/checker.ts | 4 ++++ src/compiler/types.ts | 1 + src/services/organizeImports.ts | 4 +++- .../unittests/services/organizeImports.ts | 18 ++++++++++++++++++ .../organizeImports/JsxFragmentPragmaTsx.ts | 13 +++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/organizeImports/JsxFragmentPragmaTsx.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 47fd8d85cc5..2548d12c125 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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 => { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8fc3a1457cd..7c9038ed3ba 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -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: diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 46eda4b00a9..c67b9df12e4 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -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); } } diff --git a/src/testRunner/unittests/services/organizeImports.ts b/src/testRunner/unittests/services/organizeImports.ts index 3e2b1108931..13f3f126c9e 100644 --- a/src/testRunner/unittests/services/organizeImports.ts +++ b/src/testRunner/unittests/services/organizeImports.ts @@ -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 = <>
Foo
; +`, + }, + { + path: "/@foo/core/index.d.ts", + content: `export function h(): void; +export function frag(): void; +` + } + ); + describe("Exports", () => { testOrganizeExports("MoveToTop", diff --git a/tests/baselines/reference/organizeImports/JsxFragmentPragmaTsx.ts b/tests/baselines/reference/organizeImports/JsxFragmentPragmaTsx.ts new file mode 100644 index 00000000000..1dbdfd05dc9 --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFragmentPragmaTsx.ts @@ -0,0 +1,13 @@ +// ==ORIGINAL== +/** @jsx h */ +/** @jsxFrag frag */ +import { h, frag } from "@foo/core"; + +const elem = <>
Foo
; + +// ==ORGANIZED== +/** @jsx h */ +/** @jsxFrag frag */ +import { frag, h } from "@foo/core"; + +const elem = <>
Foo
;