Skip to content

Remove reference not found errors from jsx: preserve #60687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30014,14 +30014,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 @@ -30046,7 +30047,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 @@ -36835,12 +36836,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// #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 shouldFactoryRefErr = compilerOptions.jsx !== JsxEmit.Preserve && compilerOptions.jsx !== JsxEmit.ReactNative;
const jsxFactoryRefErr = diagnostics && shouldFactoryRefErr ? 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,
shouldFactoryRefErr ? 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,16 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

//// [jsxFragmentFactoryReference.tsx]
export class LoggedOut {
content = () => (
<> </>
)
}


//// [jsxFragmentFactoryReference.jsx]
export class LoggedOut {
constructor() {
this.content = () => (<> </>);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : Symbol(LoggedOut, Decl(jsxFragmentFactoryReference.tsx, 0, 0))

content = () => (
>content : Symbol(LoggedOut.content, Decl(jsxFragmentFactoryReference.tsx, 0, 24))

<> </>
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : LoggedOut
> : ^^^^^^^^^

content = () => (
>content : () => any
> : ^^^^^^^^^
>() => ( <> </> ) : () => any
> : ^^^^^^^^^
>( <> </> ) : any

<> </>
><> </> : any

)
}

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,16 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

//// [jsxFragmentFactoryReference.tsx]
export class LoggedOut {
content = () => (
<> </>
)
}


//// [jsxFragmentFactoryReference.js]
export class LoggedOut {
constructor() {
this.content = () => (React.createElement(React.Fragment, null, " "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : Symbol(LoggedOut, Decl(jsxFragmentFactoryReference.tsx, 0, 0))

content = () => (
>content : Symbol(LoggedOut.content, Decl(jsxFragmentFactoryReference.tsx, 0, 24))

<> </>
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : LoggedOut
> : ^^^^^^^^^

content = () => (
>content : () => any
> : ^^^^^^^^^
>() => ( <> </> ) : () => any
> : ^^^^^^^^^
>( <> </> ) : any
> : ^^^

<> </>
><> </> : any
> : ^^^

)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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(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 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?
~~
!!! 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,17 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

//// [jsxFragmentFactoryReference.tsx]
export class LoggedOut {
content = () => (
<> </>
)
}


//// [jsxFragmentFactoryReference.js]
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
export class LoggedOut {
constructor() {
this.content = () => (_jsx(_Fragment, { children: " " }));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : Symbol(LoggedOut, Decl(jsxFragmentFactoryReference.tsx, 0, 0))

content = () => (
>content : Symbol(LoggedOut.content, Decl(jsxFragmentFactoryReference.tsx, 0, 24))

<> </>
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//// [tests/cases/compiler/jsxFragmentFactoryReference.tsx] ////

=== jsxFragmentFactoryReference.tsx ===
export class LoggedOut {
>LoggedOut : LoggedOut
> : ^^^^^^^^^

content = () => (
>content : () => any
> : ^^^^^^^^^
>() => ( <> </> ) : () => any
> : ^^^^^^^^^
>( <> </> ) : any
> : ^^^

<> </>
><> </> : any
> : ^^^

)
}

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");
Loading
Loading