Skip to content

Commit b07eb63

Browse files
committed
Merge pull request #7645 from Microsoft/fix7637
Fix #7637: treat jsx tag names as expressions
2 parents 9094e01 + 3ee67e7 commit b07eb63

14 files changed

+81
-35
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9033,7 +9033,12 @@ namespace ts {
90339033
checkJsxOpeningLikeElement(node.openingElement);
90349034

90359035
// Perform resolution on the closing tag so that rename/go to definition/etc work
9036-
getJsxTagSymbol(node.closingElement);
9036+
if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
9037+
getIntrinsicTagSymbol(node.closingElement);
9038+
}
9039+
else {
9040+
checkExpression(node.closingElement.tagName);
9041+
}
90379042

90389043
// Check children
90399044
for (const child of node.children) {
@@ -9143,18 +9148,6 @@ namespace ts {
91439148
return jsxTypes[name];
91449149
}
91459150

9146-
function getJsxTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
9147-
if (isJsxIntrinsicIdentifier(node.tagName)) {
9148-
return getIntrinsicTagSymbol(node);
9149-
}
9150-
else if (node.tagName.kind === SyntaxKind.Identifier) {
9151-
return resolveEntityName(node.tagName, SymbolFlags.Value | SymbolFlags.Alias);
9152-
}
9153-
else {
9154-
return checkExpression(node.tagName).symbol;
9155-
}
9156-
}
9157-
91589151
/**
91599152
* Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
91609153
* property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
@@ -16211,19 +16204,17 @@ namespace ts {
1621116204
meaning |= SymbolFlags.Alias;
1621216205
return resolveEntityName(<EntityName>entityName, meaning);
1621316206
}
16214-
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
16215-
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
16216-
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
16217-
16218-
return getJsxTagSymbol(<JsxOpeningLikeElement>entityName.parent);
16219-
}
1622016207
else if (isExpression(entityName)) {
1622116208
if (nodeIsMissing(entityName)) {
1622216209
// Missing entity name.
1622316210
return undefined;
1622416211
}
1622516212

1622616213
if (entityName.kind === SyntaxKind.Identifier) {
16214+
if (isJSXTagName(entityName) && isJsxIntrinsicIdentifier(<Identifier>entityName)) {
16215+
return getIntrinsicTagSymbol(<JsxOpeningLikeElement>entityName.parent);
16216+
}
16217+
1622716218
// Include aliases in the meaning, this ensures that we do not follow aliases to where they point and instead
1622816219
// return the alias symbol.
1622916220
const meaning: SymbolFlags = SymbolFlags.Value | SymbolFlags.Alias;

src/compiler/utilities.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,16 @@ namespace ts {
953953
return node.kind === SyntaxKind.ElementAccessExpression;
954954
}
955955

956+
export function isJSXTagName(node: Node) {
957+
const parent = node.parent;
958+
if (parent.kind === SyntaxKind.JsxOpeningElement ||
959+
parent.kind === SyntaxKind.JsxSelfClosingElement ||
960+
parent.kind === SyntaxKind.JsxClosingElement) {
961+
return (<JsxOpeningLikeElement>parent).tagName === node;
962+
}
963+
return false;
964+
}
965+
956966
export function isExpression(node: Node): boolean {
957967
switch (node.kind) {
958968
case SyntaxKind.SuperKeyword:
@@ -994,9 +1004,9 @@ namespace ts {
9941004
while (node.parent.kind === SyntaxKind.QualifiedName) {
9951005
node = node.parent;
9961006
}
997-
return node.parent.kind === SyntaxKind.TypeQuery;
1007+
return node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node);
9981008
case SyntaxKind.Identifier:
999-
if (node.parent.kind === SyntaxKind.TypeQuery) {
1009+
if (node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node)) {
10001010
return true;
10011011
}
10021012
// fall through

tests/baselines/reference/jsxReactTestSuite.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ var x =
178178
>constructor : Symbol(unknown)
179179

180180
<Namespace.Component />;
181+
>Namespace : Symbol(Namespace, Decl(jsxReactTestSuite.tsx, 6, 11))
181182

182183
<Namespace.DeepNamespace.Component />;
184+
>Namespace : Symbol(Namespace, Decl(jsxReactTestSuite.tsx, 6, 11))
183185

184186
<Component { ... x } y
185187
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))

tests/baselines/reference/jsxReactTestSuite.types

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,14 @@ var x =
235235

236236
<Namespace.Component />;
237237
><Namespace.Component /> : any
238+
>Namespace.Component : any
238239
>Namespace : any
239240
>Component : any
240241

241242
<Namespace.DeepNamespace.Component />;
242243
><Namespace.DeepNamespace.Component /> : any
244+
>Namespace.DeepNamespace.Component : any
245+
>Namespace.DeepNamespace : any
243246
>Namespace : any
244247
>DeepNamespace : any
245248
>Component : any

tests/baselines/reference/tsxAttributeResolution13.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ function Test() { }
55

66
<Test></Test>
77
><Test></Test> : any
8-
>Test : any
9-
>Test : any
8+
>Test : () => void
9+
>Test : () => void
1010

tests/baselines/reference/tsxElementResolution.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,7 @@ var d = <Other />;
4747

4848
var e = <Dotted.Name />;
4949
>e : Symbol(e, Decl(tsxElementResolution.tsx, 23, 3))
50+
>Dotted.Name : Symbol(Dotted.Name, Decl(tsxElementResolution.tsx, 12, 15))
51+
>Dotted : Symbol(Dotted, Decl(tsxElementResolution.tsx, 10, 14))
5052
>Name : Symbol(Dotted.Name, Decl(tsxElementResolution.tsx, 12, 15))
5153

tests/baselines/reference/tsxElementResolution.types

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var d = <Other />;
5151
var e = <Dotted.Name />;
5252
>e : any
5353
><Dotted.Name /> : any
54-
>Dotted : any
55-
>Name : any
54+
>Dotted.Name : typeof Dotted.Name
55+
>Dotted : typeof Dotted
56+
>Name : typeof Dotted.Name
5657

tests/baselines/reference/tsxElementResolution17.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import s2 = require('elements2');
88
>s2 : Symbol(s2, Decl(consumer.tsx, 2, 33))
99

1010
<s1.MyElement />;
11+
>s1.MyElement : Symbol(s1.MyElement, Decl(file.tsx, 6, 28))
12+
>s1 : Symbol(s1, Decl(consumer.tsx, 0, 0))
1113
>MyElement : Symbol(s1.MyElement, Decl(file.tsx, 6, 28))
1214

1315
=== tests/cases/conformance/jsx/file.tsx ===

tests/baselines/reference/tsxElementResolution17.types

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import s2 = require('elements2');
99

1010
<s1.MyElement />;
1111
><s1.MyElement /> : JSX.Element
12-
>s1 : any
13-
>MyElement : any
12+
>s1.MyElement : typeof s1.MyElement
13+
>s1 : typeof s1
14+
>MyElement : typeof s1.MyElement
1415

1516
=== tests/cases/conformance/jsx/file.tsx ===
1617

tests/baselines/reference/tsxEmit3.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ module M {
5959
>S.Bar : Symbol(S.Bar, Decl(file.tsx, 8, 18))
6060
>S : Symbol(S, Decl(file.tsx, 7, 39), Decl(file.tsx, 18, 14))
6161
>Bar : Symbol(S.Bar, Decl(file.tsx, 8, 18))
62+
>S.Bar : Symbol(S.Bar, Decl(file.tsx, 8, 18))
63+
>S : Symbol(S, Decl(file.tsx, 7, 39), Decl(file.tsx, 18, 14))
6264
>Bar : Symbol(S.Bar, Decl(file.tsx, 8, 18))
6365
}
6466

tests/baselines/reference/tsxEmit3.types

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ module M {
6767
>S : typeof S
6868
>Bar : typeof S.Bar
6969
><S.Bar /> : JSX.Element
70-
>S : any
71-
>Bar : any
70+
>S.Bar : typeof S.Bar
71+
>S : typeof S
72+
>Bar : typeof S.Bar
7273
}
7374

7475
module M {

tests/baselines/reference/tsxOpeningClosingNames.symbols

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,18 @@ declare module A.B.C {
1616
}
1717

1818
<A.B.C.D>foo</A . B . C.D>
19+
>A.B.C.D : Symbol(A.B.C.D, Decl(file.tsx, 5, 5))
20+
>A.B.C : Symbol(A.B.C, Decl(file.tsx, 4, 19))
21+
>A.B : Symbol(A.B, Decl(file.tsx, 4, 17))
22+
>A : Symbol(A, Decl(file.tsx, 2, 1))
23+
>B : Symbol(A.B, Decl(file.tsx, 4, 17))
24+
>C : Symbol(A.B.C, Decl(file.tsx, 4, 19))
25+
>D : Symbol(A.B.C.D, Decl(file.tsx, 5, 5))
26+
>A . B . C.D : Symbol(A.B.C.D, Decl(file.tsx, 5, 5))
27+
>A . B . C : Symbol(A.B.C, Decl(file.tsx, 4, 19))
28+
>A . B : Symbol(A.B, Decl(file.tsx, 4, 17))
29+
>A : Symbol(A, Decl(file.tsx, 2, 1))
30+
>B : Symbol(A.B, Decl(file.tsx, 4, 17))
31+
>C : Symbol(A.B.C, Decl(file.tsx, 4, 19))
32+
>D : Symbol(A.B.C.D, Decl(file.tsx, 5, 5))
1933

tests/baselines/reference/tsxOpeningClosingNames.types

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@ declare module A.B.C {
1717

1818
<A.B.C.D>foo</A . B . C.D>
1919
><A.B.C.D>foo</A . B . C.D> : JSX.Element
20-
>A : any
21-
>B : any
22-
>C : any
20+
>A.B.C.D : any
21+
>A.B.C : typeof A.B.C
22+
>A.B : typeof A.B
23+
>A : typeof A
24+
>B : typeof A.B
25+
>C : typeof A.B.C
2326
>D : any
24-
>A : any
25-
>B : any
26-
>C : any
27+
>A . B . C.D : any
28+
>A . B . C : typeof A.B.C
29+
>A . B : typeof A.B
30+
>A : typeof A
31+
>B : typeof A.B
32+
>C : typeof A.B.C
2733
>D : any
2834

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @Filename: index.tsx
4+
////const /*1*/obj = {Component: () => <div/>};
5+
////const element = </*2*/obj.Component/>;
6+
7+
goTo.marker("1");
8+
verify.referencesCountIs(2);
9+
10+
goTo.marker("2");
11+
verify.referencesCountIs(2);

0 commit comments

Comments
 (0)