Skip to content

Commit

Permalink
Remove reference not found errors from jsx: preserve (#60687)
Browse files Browse the repository at this point in the history
  • Loading branch information
iisaduan authored Dec 9, 2024
1 parent 421f5c5 commit 3d2b8f3
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 29 deletions.
12 changes: 8 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30015,14 +30015,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.This_JSX_tag_requires_0_to_be_in_scope_but_it_could_not_be_found : undefined;
const jsxFactoryNamespace = getJsxNamespace(node);
const jsxFactoryLocation = isJsxOpeningLikeElement(node) ? node.tagName : node;
const shouldFactoryRefErr = compilerOptions.jsx !== JsxEmit.Preserve && compilerOptions.jsx !== JsxEmit.ReactNative;

// #38720/60122, allow null as jsxFragmentFactory
let jsxFactorySym: Symbol | undefined;
if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
jsxFactorySym = resolveName(
jsxFactoryLocation,
jsxFactoryNamespace,
(compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value,
shouldFactoryRefErr ? SymbolFlags.Value : SymbolFlags.Value & ~SymbolFlags.Enum,
jsxFactoryRefErr,
/*isUse*/ true,
);
Expand All @@ -30048,7 +30049,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
resolveName(
jsxFactoryLocation,
localJsxNamespace,
(compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value,
shouldFactoryRefErr ? SymbolFlags.Value : SymbolFlags.Value & ~SymbolFlags.Enum,
jsxFactoryRefErr,
/*isUse*/ true,
);
Expand Down Expand Up @@ -36841,15 +36842,18 @@ 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 shouldResolveFactoryReference = (compilerOptions.jsx === JsxEmit.React || compilerOptions.jsxFragmentFactory !== undefined) && jsxFragmentFactoryName !== "null";
if (!shouldResolveFactoryReference) return sourceFileLinks.jsxFragmentType = anyType;

const shouldModuleRefErr = compilerOptions.jsx !== JsxEmit.Preserve && compilerOptions.jsx !== JsxEmit.ReactNative;
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,
(compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value,
shouldModuleRefErr ? SymbolFlags.Value : SymbolFlags.Value & ~SymbolFlags.Enum,
/*nameNotFoundMessage*/ jsxFactoryRefErr,
/*isUse*/ true,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
jsxFragmentFactoryReference.tsx(3,9): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
jsxFragmentFactoryReference.tsx(3,9): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.


==== jsxFragmentFactoryReference.tsx (2 errors) ====
export class LoggedOut {
content = () => (
<></>
~~
!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
jsxFragmentFactoryReference.tsx(3,9): error TS2792: Cannot find module 'react/jsx-runtime'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?


==== jsxFragmentFactoryReference.tsx (1 errors) ====
export class LoggedOut {
content = () => (
<></>
~~
!!! error TS2792: Cannot find module 'react/jsx-runtime'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
jsxFragmentFactoryReference.tsx(3,9): error TS2792: Cannot find module 'react/jsx-dev-runtime'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?


==== jsxFragmentFactoryReference.tsx (1 errors) ====
export class LoggedOut {
content = () => (
<></>
~~
!!! error TS2792: Cannot find module 'react/jsx-dev-runtime'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
)
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.


==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ====
==== jsxJsxsCjsTransformCustomImport.tsx (1 errors) ====
/// <reference path="/.lib/react16.d.ts" />
const a = <>
~~
!!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.
<p></p>
text
<div className="foo"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.


==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ====
==== jsxJsxsCjsTransformCustomImport.tsx (1 errors) ====
/// <reference path="/.lib/react16.d.ts" />
const a = <>
~~
!!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.
<p></p>
text
<div className="foo"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.


==== react.tsx (0 errors) ====
Expand All @@ -13,14 +12,12 @@ preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'R
</>

export {};
==== preact.tsx (2 errors) ====
==== preact.tsx (1 errors) ====
/// <reference path="/.lib/react16.d.ts" />
/* @jsxImportSource preact */
const a = <>
~~
!!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.
<p></p>
text
<div className="foo"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.


==== react.tsx (0 errors) ====
Expand All @@ -13,14 +12,12 @@ preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'R
</>

export {};
==== preact.tsx (2 errors) ====
==== preact.tsx (1 errors) ====
/// <reference path="/.lib/react16.d.ts" />
/* @jsxImportSource preact */
const a = <>
~~
!!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
~~
!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.
<p></p>
text
<div className="foo"></div>
Expand Down
88 changes: 88 additions & 0 deletions tests/baselines/reference/jsxRuntimePragma(jsx=preserve).js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//// [tests/cases/compiler/jsxRuntimePragma.ts] ////

//// [one.tsx]
/// <reference path="/.lib/react16.d.ts" />
/* @jsxRuntime classic */
import * as React from "react";
export const HelloWorld = () => <h1>Hello world</h1>;
export const frag = <><div></div></>;
export const selfClosing = <img src="./image.png" />;
//// [two.tsx]
/// <reference path="/.lib/react16.d.ts" />
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;
export const frag = <><div></div></>;
export const selfClosing = <img src="./image.png" />;
//// [three.tsx]
/// <reference path="/.lib/react16.d.ts" />
/* @jsxRuntime classic */
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;
export const frag = <><div></div></>;
export const selfClosing = <img src="./image.png" />;
//// [four.tsx]
/// <reference path="/.lib/react16.d.ts" />
/* @jsxRuntime automatic */
/* @jsxRuntime classic */
import * as React from "react";
export const HelloWorld = () => <h1>Hello world</h1>;
export const frag = <><div></div></>;
export const selfClosing = <img src="./image.png" />;
//// [index.ts]
export * as one from "./one.js";
export * as two from "./two.js";
export * as three from "./three.js";
export * as four from "./four.js";

//// [one.jsx]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.selfClosing = exports.frag = exports.HelloWorld = void 0;
/// <reference path="react16.d.ts" />
/* @jsxRuntime classic */
var React = require("react");
var HelloWorld = function () { return <h1>Hello world</h1>; };
exports.HelloWorld = HelloWorld;
exports.frag = <><div></div></>;
exports.selfClosing = <img src="./image.png"/>;
//// [two.jsx]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.selfClosing = exports.frag = exports.HelloWorld = void 0;
/// <reference path="react16.d.ts" />
/* @jsxRuntime automatic */
var HelloWorld = function () { return <h1>Hello world</h1>; };
exports.HelloWorld = HelloWorld;
exports.frag = <><div></div></>;
exports.selfClosing = <img src="./image.png"/>;
//// [three.jsx]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.selfClosing = exports.frag = exports.HelloWorld = void 0;
/// <reference path="react16.d.ts" />
/* @jsxRuntime classic */
/* @jsxRuntime automatic */
var HelloWorld = function () { return <h1>Hello world</h1>; };
exports.HelloWorld = HelloWorld;
exports.frag = <><div></div></>;
exports.selfClosing = <img src="./image.png"/>;
//// [four.jsx]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.selfClosing = exports.frag = exports.HelloWorld = void 0;
/// <reference path="react16.d.ts" />
/* @jsxRuntime automatic */
/* @jsxRuntime classic */
var React = require("react");
var HelloWorld = function () { return <h1>Hello world</h1>; };
exports.HelloWorld = HelloWorld;
exports.frag = <><div></div></>;
exports.selfClosing = <img src="./image.png"/>;
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.four = exports.three = exports.two = exports.one = void 0;
exports.one = require("./one.js");
exports.two = require("./two.js");
exports.three = require("./three.js");
exports.four = require("./four.js");
95 changes: 95 additions & 0 deletions tests/baselines/reference/jsxRuntimePragma(jsx=preserve).symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//// [tests/cases/compiler/jsxRuntimePragma.ts] ////

=== one.tsx ===
/// <reference path="react16.d.ts" />
/* @jsxRuntime classic */
import * as React from "react";
>React : Symbol(React, Decl(one.tsx, 2, 6))

export const HelloWorld = () => <h1>Hello world</h1>;
>HelloWorld : Symbol(HelloWorld, Decl(one.tsx, 3, 12))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))

export const frag = <><div></div></>;
>frag : Symbol(frag, Decl(one.tsx, 4, 12))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))

export const selfClosing = <img src="./image.png" />;
>selfClosing : Symbol(selfClosing, Decl(one.tsx, 5, 12))
>img : Symbol(JSX.IntrinsicElements.img, Decl(react16.d.ts, 2569, 114))
>src : Symbol(src, Decl(one.tsx, 5, 31))

=== two.tsx ===
/// <reference path="react16.d.ts" />
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;
>HelloWorld : Symbol(HelloWorld, Decl(two.tsx, 2, 12))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))

export const frag = <><div></div></>;
>frag : Symbol(frag, Decl(two.tsx, 3, 12))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))

export const selfClosing = <img src="./image.png" />;
>selfClosing : Symbol(selfClosing, Decl(two.tsx, 4, 12))
>img : Symbol(JSX.IntrinsicElements.img, Decl(react16.d.ts, 2569, 114))
>src : Symbol(src, Decl(two.tsx, 4, 31))

=== three.tsx ===
/// <reference path="react16.d.ts" />
/* @jsxRuntime classic */
/* @jsxRuntime automatic */
export const HelloWorld = () => <h1>Hello world</h1>;
>HelloWorld : Symbol(HelloWorld, Decl(three.tsx, 3, 12))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))

export const frag = <><div></div></>;
>frag : Symbol(frag, Decl(three.tsx, 4, 12))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))

export const selfClosing = <img src="./image.png" />;
>selfClosing : Symbol(selfClosing, Decl(three.tsx, 5, 12))
>img : Symbol(JSX.IntrinsicElements.img, Decl(react16.d.ts, 2569, 114))
>src : Symbol(src, Decl(three.tsx, 5, 31))

=== four.tsx ===
/// <reference path="react16.d.ts" />
/* @jsxRuntime automatic */
/* @jsxRuntime classic */
import * as React from "react";
>React : Symbol(React, Decl(four.tsx, 3, 6))

export const HelloWorld = () => <h1>Hello world</h1>;
>HelloWorld : Symbol(HelloWorld, Decl(four.tsx, 4, 12))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react16.d.ts, 2556, 106))

export const frag = <><div></div></>;
>frag : Symbol(frag, Decl(four.tsx, 5, 12))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114))

export const selfClosing = <img src="./image.png" />;
>selfClosing : Symbol(selfClosing, Decl(four.tsx, 6, 12))
>img : Symbol(JSX.IntrinsicElements.img, Decl(react16.d.ts, 2569, 114))
>src : Symbol(src, Decl(four.tsx, 6, 31))

=== index.ts ===
export * as one from "./one.js";
>one : Symbol(one, Decl(index.ts, 0, 6))

export * as two from "./two.js";
>two : Symbol(two, Decl(index.ts, 1, 6))

export * as three from "./three.js";
>three : Symbol(three, Decl(index.ts, 2, 6))

export * as four from "./four.js";
>four : Symbol(four, Decl(index.ts, 3, 6))

Loading

0 comments on commit 3d2b8f3

Please sign in to comment.