fix fragment resolving behavior with jsx: preserve and jsxFragmentFactory: null (#60122)

This commit is contained in:
Isabel Duan 2024-10-04 11:47:59 -07:00 committed by GitHub
parent ca18009b8b
commit b845fd2434
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 23 additions and 102 deletions

View File

@ -29873,10 +29873,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const jsxFactoryNamespace = getJsxNamespace(node);
const jsxFactoryLocation = isJsxOpeningLikeElement(node) ? node.tagName : node;
// allow null as jsxFragmentFactory
// #38720/60122, allow null as jsxFragmentFactory
let jsxFactorySym: Symbol | undefined;
if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
}
if (jsxFactorySym) {
@ -29890,12 +29890,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
// For JsxFragment, mark jsx pragma as referenced via resolveName
// if JsxFragment, additionally mark jsx pragma as referenced, since `getJsxNamespace` above would have resolved to only the fragment factory if they are distinct
if (isJsxOpeningFragment(node)) {
const file = getSourceFileOfNode(node);
const localJsxNamespace = getLocalJsxNamespace(file);
if (localJsxNamespace) {
resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
resolveName(jsxFactoryLocation, localJsxNamespace, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
}
}
}
@ -32918,7 +32918,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
checkJsxChildren(node);
return getJsxElementTypeAt(node) || anyType;
const jsxElementType = getJsxElementTypeAt(node);
return isErrorType(jsxElementType) ? anyType : jsxElementType;
}
function isHyphenatedJsxName(name: string | __String) {
@ -36643,9 +36644,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (sourceFileLinks.jsxFragmentType !== undefined) return sourceFileLinks.jsxFragmentType;
const jsxFragmentFactoryName = getJsxNamespace(node);
// #38720/60122, allow null as jsxFragmentFactory
if (jsxFragmentFactoryName === "null") return sourceFileLinks.jsxFragmentType = anyType;
const jsxFactoryRefErr = diagnostics ? Diagnostics.Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found : undefined;
const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ??
resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true);
resolveName(node, jsxFragmentFactoryName, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true);
if (jsxFactorySymbol === undefined) return sourceFileLinks.jsxFragmentType = errorType;
if (jsxFactorySymbol.escapedName === ReactNames.Fragment) return sourceFileLinks.jsxFragmentType = getTypeOfSymbol(jsxFactorySymbol);

View File

@ -1,9 +1,6 @@
preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read.
preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found.
snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found.
snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
snabbdomy-only-fragment.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
snabbdomy.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== renderer.d.ts (0 errors) ====
@ -26,13 +23,11 @@ snabbdomy.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory
import {h, Fragment} from "./renderer";
<><div></div></>
==== snabbdomy.tsx (1 errors) ====
==== snabbdomy.tsx (0 errors) ====
/* @jsx jsx */
/* @jsxfrag null */
import {jsx} from "./renderer";
<><span></span></>
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== preacty-only-fragment.tsx (0 errors) ====
/**
@ -42,13 +37,11 @@ snabbdomy.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory
import {h, Fragment} from "./renderer";
<></>
==== snabbdomy-only-fragment.tsx (1 errors) ====
==== snabbdomy-only-fragment.tsx (0 errors) ====
/* @jsx jsx */
/* @jsxfrag null */
import {jsx} from "./renderer";
<></>
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== preacty-only-fragment-no-jsx.tsx (1 errors) ====
/**
@ -60,15 +53,13 @@ snabbdomy.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory
~~
!!! error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found.
==== snabbdomy-only-fragment-no-jsx.tsx (2 errors) ====
==== snabbdomy-only-fragment-no-jsx.tsx (1 errors) ====
/* @jsx jsx */
/* @jsxfrag null */
import {} from "./renderer";
<></>
~~
!!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== preacty-no-fragment.tsx (1 errors) ====
/**

View File

@ -1,49 +0,0 @@
snabbdomy.tsx(6,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== react.d.ts (0 errors) ====
declare global {
namespace JSX {
interface IntrinsicElements {
[e: string]: any;
}
}
}
export function createElement(): void;
export function Fragment(): void;
==== preact.d.ts (0 errors) ====
export function h(): void;
export function Frag(): void;
==== snabbdom.d.ts (0 errors) ====
export function h(): void;
==== reacty.tsx (0 errors) ====
import {createElement, Fragment} from "./react";
<><span></span></>
==== preacty.tsx (0 errors) ====
/**
* @jsx h
* @jsxFrag Frag
*/
import {h, Frag} from "./preact";
<><div></div></>
==== snabbdomy.tsx (1 errors) ====
/**
* @jsx h
* @jsxfrag null
*/
import {h} from "./snabbdom";
<><div></div></>
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== mix-n-match.tsx (0 errors) ====
/* @jsx h */
/* @jsxFrag Fragment */
import {h} from "./preact";
import {Fragment} from "./react";
<><span></span></>

View File

@ -44,9 +44,7 @@ import {createElement, Fragment} from "./react";
<><span></span></>
><><span></span></> : any
> : ^^^
><span></span> : any
> : ^^^
><span></span> : error
>span : any
> : ^^^
>span : any
@ -65,9 +63,7 @@ import {h, Frag} from "./preact";
<><div></div></>
><><div></div></> : any
> : ^^^
><div></div> : any
> : ^^^
><div></div> : error
>div : any
> : ^^^
>div : any
@ -84,9 +80,7 @@ import {h} from "./snabbdom";
<><div></div></>
><><div></div></> : any
> : ^^^
><div></div> : any
> : ^^^
><div></div> : error
>div : any
> : ^^^
>div : any
@ -105,9 +99,7 @@ import {Fragment} from "./react";
<><span></span></>
><><span></span></> : any
> : ^^^
><span></span> : any
> : ^^^
><span></span> : error
>span : any
> : ^^^
>span : any

View File

@ -8,16 +8,16 @@ declare var Frag: any;
>Frag : any
<></>;
><></> : error
><></> : any
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
><><span>1</span><><span>2.1</span><span>2.2</span></></> : error
><><span>1</span><><span>2.1</span><span>2.2</span></></> : any
><span>1</span> : error
>span : any
> : ^^^
>span : any
> : ^^^
><><span>2.1</span><span>2.2</span></> : error
><><span>2.1</span><span>2.2</span></> : any
><span>2.1</span> : error
>span : any
> : ^^^

View File

@ -1,10 +0,0 @@
jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ====
declare var h: any;
<></>;
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found.
<><span>1</span><><span>2.1</span><span>2.2</span></></>;

View File

@ -3,31 +3,24 @@
=== jsxFactoryAndJsxFragmentFactoryNull.tsx ===
declare var h: any;
>h : any
> : ^^^
<></>;
><></> : any
> : ^^^
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
><><span>1</span><><span>2.1</span><span>2.2</span></></> : any
> : ^^^
><span>1</span> : any
> : ^^^
><span>1</span> : error
>span : any
> : ^^^
>span : any
> : ^^^
><><span>2.1</span><span>2.2</span></> : any
> : ^^^
><span>2.1</span> : any
> : ^^^
><span>2.1</span> : error
>span : any
> : ^^^
>span : any
> : ^^^
><span>2.2</span> : any
> : ^^^
><span>2.2</span> : error
>span : any
> : ^^^
>span : any