Skip to content

Commit

Permalink
fix fragment resolving behavior with jsx: preserve and `jsxFragment…
Browse files Browse the repository at this point in the history
…Factory: null` (#60122)
  • Loading branch information
iisaduan authored Oct 4, 2024
1 parent ca18009 commit b845fd2
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 102 deletions.
16 changes: 10 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 3 additions & 12 deletions tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt
Original file line number Diff line number Diff line change
@@ -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) ====
Expand All @@ -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) ====
/**
Expand All @@ -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) ====
/**
Expand All @@ -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) ====
/**
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ import {createElement, Fragment} from "./react";

<><span></span></>
><><span></span></> : any
> : ^^^
><span></span> : any
> : ^^^
><span></span> : error
>span : any
> : ^^^
>span : any
Expand All @@ -65,9 +63,7 @@ import {h, Frag} from "./preact";

<><div></div></>
><><div></div></> : any
> : ^^^
><div></div> : any
> : ^^^
><div></div> : error
>div : any
> : ^^^
>div : any
Expand All @@ -84,9 +80,7 @@ import {h} from "./snabbdom";

<><div></div></>
><><div></div></> : any
> : ^^^
><div></div> : any
> : ^^^
><div></div> : error
>div : any
> : ^^^
>div : any
Expand All @@ -105,9 +99,7 @@ import {Fragment} from "./react";

<><span></span></>
><><span></span></> : any
> : ^^^
><span></span> : any
> : ^^^
><span></span> : error
>span : any
> : ^^^
>span : any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
> : ^^^
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit b845fd2

Please sign in to comment.