Skip to content

Commit ef9affe

Browse files
authored
Use jsxFragmentFactory entity name for factory name lookup from checking fragments (microsoft#39475)
1 parent ececf3b commit ef9affe

9 files changed

+150
-0
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,11 @@ namespace ts {
968968
return file.localJsxFragmentNamespace = getFirstIdentifier(file.localJsxFragmentFactory).escapedText;
969969
}
970970
}
971+
const entity = getJsxFragmentFactoryEntity(location);
972+
if (entity) {
973+
file.localJsxFragmentFactory = entity;
974+
return file.localJsxFragmentNamespace = getFirstIdentifier(entity).escapedText;
975+
}
971976
}
972977
else {
973978
if (file.localJsxNamespace) {

tests/baselines/reference/jsxFactoryAndJsxFragmentFactory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//// [jsxFactoryAndJsxFragmentFactory.tsx]
22
declare var h: any;
3+
declare var Frag: any;
34

45
<></>;
56
<><span>1</span><><span>2.1</span><span>2.2</span></></>;

tests/baselines/reference/jsxFactoryAndJsxFragmentFactory.symbols

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
declare var h: any;
33
>h : Symbol(h, Decl(jsxFactoryAndJsxFragmentFactory.tsx, 0, 11))
44

5+
declare var Frag: any;
6+
>Frag : Symbol(Frag, Decl(jsxFactoryAndJsxFragmentFactory.tsx, 1, 11))
7+
58
<></>;
69
<><span>1</span><><span>2.1</span><span>2.2</span></></>;

tests/baselines/reference/jsxFactoryAndJsxFragmentFactory.types

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
declare var h: any;
33
>h : any
44

5+
declare var Frag: any;
6+
>Frag : any
7+
58
<></>;
69
><></> : error
710

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [jsxFragmentFactoryNoUnusedLocals.tsx]
2+
/// <reference path="/.lib/react16.d.ts" />
3+
import { Fragment, createElement } from "react"
4+
5+
type CounterProps = {
6+
count?: number
7+
}
8+
9+
export function Counter({ count = 0 }: CounterProps) {
10+
const [cnt, setCnt] = null as any;
11+
return <>
12+
<p>{cnt}</p>
13+
<button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button>
14+
</>
15+
}
16+
17+
//// [jsxFragmentFactoryNoUnusedLocals.js]
18+
"use strict";
19+
exports.__esModule = true;
20+
exports.Counter = void 0;
21+
/// <reference path="react16.d.ts" />
22+
var react_1 = require("react");
23+
function Counter(_a) {
24+
var _b = _a.count, count = _b === void 0 ? 0 : _b;
25+
var _c = null, cnt = _c[0], setCnt = _c[1];
26+
return react_1.createElement(react_1.Fragment, null,
27+
react_1.createElement("p", null, cnt),
28+
react_1.createElement("button", { onClick: function () { return setCnt(function (prev) { return prev + 1; }); }, type: "button" }, "Update"));
29+
}
30+
exports.Counter = Counter;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/compiler/jsxFragmentFactoryNoUnusedLocals.tsx ===
2+
/// <reference path="react16.d.ts" />
3+
import { Fragment, createElement } from "react"
4+
>Fragment : Symbol(Fragment, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 1, 8))
5+
>createElement : Symbol(createElement, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 1, 18))
6+
7+
type CounterProps = {
8+
>CounterProps : Symbol(CounterProps, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 1, 47))
9+
10+
count?: number
11+
>count : Symbol(count, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 3, 21))
12+
}
13+
14+
export function Counter({ count = 0 }: CounterProps) {
15+
>Counter : Symbol(Counter, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 5, 1))
16+
>count : Symbol(count, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 7, 25))
17+
>CounterProps : Symbol(CounterProps, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 1, 47))
18+
19+
const [cnt, setCnt] = null as any;
20+
>cnt : Symbol(cnt, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 8, 11))
21+
>setCnt : Symbol(setCnt, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 8, 15))
22+
23+
return <>
24+
<p>{cnt}</p>
25+
>p : Symbol(JSX.IntrinsicElements.p, Decl(react16.d.ts, 2467, 102))
26+
>cnt : Symbol(cnt, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 8, 11))
27+
>p : Symbol(JSX.IntrinsicElements.p, Decl(react16.d.ts, 2467, 102))
28+
29+
<button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button>
30+
>button : Symbol(JSX.IntrinsicElements.button, Decl(react16.d.ts, 2406, 96))
31+
>onClick : Symbol(onClick, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 11, 15))
32+
>setCnt : Symbol(setCnt, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 8, 15))
33+
>prev : Symbol(prev, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 11, 39))
34+
>prev : Symbol(prev, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 11, 39))
35+
>type : Symbol(type, Decl(jsxFragmentFactoryNoUnusedLocals.tsx, 11, 58))
36+
>button : Symbol(JSX.IntrinsicElements.button, Decl(react16.d.ts, 2406, 96))
37+
38+
</>
39+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
=== tests/cases/compiler/jsxFragmentFactoryNoUnusedLocals.tsx ===
2+
/// <reference path="react16.d.ts" />
3+
import { Fragment, createElement } from "react"
4+
>Fragment : import("react").ComponentType<{}>
5+
>createElement : { (type: "input", props?: import("react").InputHTMLAttributes<HTMLInputElement> & import("react").ClassAttributes<HTMLInputElement>, ...children: import("react").ReactNode[]): import("react").DetailedReactHTMLElement<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>; <P extends import("react").HTMLAttributes<T>, T extends HTMLElement>(type: "object" | "time" | "link" | "menu" | "dialog" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "cite" | "code" | "col" | "colgroup" | "data" | "datalist" | "dd" | "del" | "details" | "dfn" | "div" | "dl" | "dt" | "em" | "embed" | "fieldset" | "figcaption" | "figure" | "footer" | "form" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hgroup" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "ins" | "kbd" | "keygen" | "label" | "legend" | "li" | "main" | "map" | "mark" | "menuitem" | "meta" | "meter" | "nav" | "noscript" | "ol" | "optgroup" | "option" | "output" | "p" | "param" | "picture" | "pre" | "progress" | "q" | "rp" | "rt" | "ruby" | "s" | "samp" | "script" | "section" | "select" | "small" | "source" | "span" | "strong" | "style" | "sub" | "summary" | "sup" | "table" | "tbody" | "td" | "textarea" | "tfoot" | "th" | "thead" | "title" | "tr" | "track" | "u" | "ul" | "var" | "video" | "wbr" | "webview", props?: import("react").ClassAttributes<T> & P, ...children: import("react").ReactNode[]): import("react").DetailedReactHTMLElement<P, T>; <P extends import("react").SVGAttributes<T>, T extends SVGElement>(type: "symbol" | "text" | "animate" | "circle" | "clipPath" | "defs" | "desc" | "ellipse" | "feBlend" | "feColorMatrix" | "feComponentTransfer" | "feComposite" | "feConvolveMatrix" | "feDiffuseLighting" | "feDisplacementMap" | "feDistantLight" | "feDropShadow" | "feFlood" | "feFuncA" | "feFuncB" | "feFuncG" | "feFuncR" | "feGaussianBlur" | "feImage" | "feMerge" | "feMergeNode" | "feMorphology" | "feOffset" | "fePointLight" | "feSpecularLighting" | "feSpotLight" | "feTile" | "feTurbulence" | "filter" | "foreignObject" | "g" | "image" | "line" | "linearGradient" | "marker" | "mask" | "metadata" | "path" | "pattern" | "polygon" | "polyline" | "radialGradient" | "rect" | "stop" | "svg" | "switch" | "textPath" | "tspan" | "use" | "view", props?: import("react").ClassAttributes<T> & P, ...children: import("react").ReactNode[]): import("react").ReactSVGElement; <P extends import("react").DOMAttributes<T>, T extends Element>(type: string, props?: import("react").ClassAttributes<T> & P, ...children: import("react").ReactNode[]): import("react").DOMElement<P, T>; <P>(type: import("react").SFC<P>, props?: import("react").Attributes & P, ...children: import("react").ReactNode[]): import("react").SFCElement<P>; <P>(type: import("react").ClassType<P, import("react").ClassicComponent<P, any>, import("react").ClassicComponentClass<P>>, props?: import("react").ClassAttributes<import("react").ClassicComponent<P, any>> & P, ...children: import("react").ReactNode[]): import("react").CElement<P, import("react").ClassicComponent<P, any>>; <P, T extends import("react").Component<P, any, any>, C extends import("react").ComponentClass<P, any>>(type: import("react").ClassType<P, T, C>, props?: import("react").ClassAttributes<T> & P, ...children: import("react").ReactNode[]): import("react").CElement<P, T>; <P>(type: string | import("react").SFC<P> | import("react").ComponentClass<P, any>, props?: import("react").Attributes & P, ...children: import("react").ReactNode[]): import("react").ReactElement<P>; }
6+
7+
type CounterProps = {
8+
>CounterProps : CounterProps
9+
10+
count?: number
11+
>count : number
12+
}
13+
14+
export function Counter({ count = 0 }: CounterProps) {
15+
>Counter : ({ count }: CounterProps) => JSX.Element
16+
>count : number
17+
>0 : 0
18+
19+
const [cnt, setCnt] = null as any;
20+
>cnt : any
21+
>setCnt : any
22+
>null as any : any
23+
>null : null
24+
25+
return <>
26+
><> <p>{cnt}</p> <button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button> </> : JSX.Element
27+
28+
<p>{cnt}</p>
29+
><p>{cnt}</p> : JSX.Element
30+
>p : any
31+
>cnt : any
32+
>p : any
33+
34+
<button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button>
35+
><button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button> : JSX.Element
36+
>button : any
37+
>onClick : () => any
38+
>() => setCnt((prev) => prev + 1) : () => any
39+
>setCnt((prev) => prev + 1) : any
40+
>setCnt : any
41+
>(prev) => prev + 1 : (prev: any) => any
42+
>prev : any
43+
>prev + 1 : any
44+
>prev : any
45+
>1 : 1
46+
>type : string
47+
>button : any
48+
49+
</>
50+
}

tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//@jsxFragmentFactory: Frag
44

55
declare var h: any;
6+
declare var Frag: any;
67

78
<></>;
89
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// @jsx: react
2+
// @jsxFactory: createElement
3+
// @jsxFragmentFactory: Fragment
4+
// @noUnusedLocals: true
5+
/// <reference path="/.lib/react16.d.ts" />
6+
import { Fragment, createElement } from "react"
7+
8+
type CounterProps = {
9+
count?: number
10+
}
11+
12+
export function Counter({ count = 0 }: CounterProps) {
13+
const [cnt, setCnt] = null as any;
14+
return <>
15+
<p>{cnt}</p>
16+
<button onClick={() => setCnt((prev) => prev + 1)} type="button">Update</button>
17+
</>
18+
}

0 commit comments

Comments
 (0)