Skip to content

Commit f682980

Browse files
committed
Merge pull request microsoft#3751 from RyanCavanaugh/fix3678
Properly parse keyword-like identifiers in JSX
2 parents 204d960 + 48c4841 commit f682980

File tree

4 files changed

+29
-14
lines changed

4 files changed

+29
-14
lines changed

src/compiler/parser.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,11 @@ namespace ts {
12461246
return isIdentifier();
12471247
}
12481248

1249+
function nextTokenIsIdentifierOrKeyword() {
1250+
nextToken();
1251+
return isIdentifierOrKeyword();
1252+
}
1253+
12491254
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
12501255
if (token === SyntaxKind.ImplementsKeyword ||
12511256
token === SyntaxKind.ExtendsKeyword) {
@@ -3172,7 +3177,7 @@ namespace ts {
31723177
if (sourceFile.languageVariant !== LanguageVariant.JSX) {
31733178
return parseTypeAssertion();
31743179
}
3175-
if(lookAhead(nextTokenIsIdentifier)) {
3180+
if(lookAhead(nextTokenIsIdentifierOrKeyword)) {
31763181
return parseJsxElementOrSelfClosingElement();
31773182
}
31783183
// Fall through
@@ -3390,7 +3395,7 @@ namespace ts {
33903395

33913396
function parseJsxElementName(): EntityName {
33923397
scanJsxIdentifier();
3393-
let elementName: EntityName = parseIdentifier();
3398+
let elementName: EntityName = parseIdentifierName();
33943399
while (parseOptional(SyntaxKind.DotToken)) {
33953400
scanJsxIdentifier();
33963401
let node = <QualifiedName>createNode(SyntaxKind.QualifiedName, elementName.pos);

tests/baselines/reference/tsxAttributeResolution1.errors.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(22,8): error TS2322: Type 'string' is not assignable to type 'number'.
2-
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(23,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
1+
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(23,8): error TS2322: Type 'string' is not assignable to type 'number'.
32
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(24,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
4-
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(25,8): error TS2322: Type 'string' is not assignable to type 'number'.
3+
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(25,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
4+
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(26,8): error TS2322: Type 'string' is not assignable to type 'number'.
5+
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(27,8): error TS2339: Property 'var' does not exist on type 'Attribs1'.
56
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(29,1): error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'.
67
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Type 'number' is not assignable to type 'string'.
78

89

9-
==== tests/cases/conformance/jsx/tsxAttributeResolution1.tsx (6 errors) ====
10+
==== tests/cases/conformance/jsx/tsxAttributeResolution1.tsx (7 errors) ====
1011
declare module JSX {
1112
interface Element { }
1213
interface IntrinsicElements {
1314
test1: Attribs1;
1415
test2: { reqd: string };
16+
var: { var: string };
1517
}
1618
}
1719
interface Attribs1 {
@@ -40,8 +42,9 @@ tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Typ
4042
<test1 x="32" />; // Error, "32" is not number
4143
~~~~~~
4244
!!! error TS2322: Type 'string' is not assignable to type 'number'.
43-
// TODO attribute 'var' should be parseable
44-
// <test1 var="10" />; // Error, no 'var' property
45+
<test1 var="10" />; // Error, no 'var' property
46+
~~~
47+
!!! error TS2339: Property 'var' does not exist on type 'Attribs1'.
4548

4649
<test2 />; // Error, missing reqd
4750
~~~~~~~~~
@@ -50,4 +53,6 @@ tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Typ
5053
~~~~~~~~~
5154
!!! error TS2322: Type 'number' is not assignable to type 'string'.
5255

56+
// Should be OK
57+
<var var='var' />;
5358

tests/baselines/reference/tsxAttributeResolution1.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ declare module JSX {
44
interface IntrinsicElements {
55
test1: Attribs1;
66
test2: { reqd: string };
7+
var: { var: string };
78
}
89
}
910
interface Attribs1 {
@@ -24,12 +25,13 @@ interface Attribs1 {
2425
<test1 y={0} />; // Error, no property "y"
2526
<test1 y="foo" />; // Error, no property "y"
2627
<test1 x="32" />; // Error, "32" is not number
27-
// TODO attribute 'var' should be parseable
28-
// <test1 var="10" />; // Error, no 'var' property
28+
<test1 var="10" />; // Error, no 'var' property
2929

3030
<test2 />; // Error, missing reqd
3131
<test2 reqd={10} />; // Error, reqd is not string
3232

33+
// Should be OK
34+
<var var='var' />;
3335

3436

3537
//// [tsxAttributeResolution1.jsx]
@@ -44,7 +46,8 @@ interface Attribs1 {
4446
<test1 y={0}/>; // Error, no property "y"
4547
<test1 y="foo"/>; // Error, no property "y"
4648
<test1 x="32"/>; // Error, "32" is not number
47-
// TODO attribute 'var' should be parseable
48-
// <test1 var="10" />; // Error, no 'var' property
49+
<test1 var="10"/>; // Error, no 'var' property
4950
<test2 />; // Error, missing reqd
5051
<test2 reqd={10}/>; // Error, reqd is not string
52+
// Should be OK
53+
<var var='var'/>;

tests/cases/conformance/jsx/tsxAttributeResolution1.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ declare module JSX {
55
interface IntrinsicElements {
66
test1: Attribs1;
77
test2: { reqd: string };
8+
var: { var: string };
89
}
910
}
1011
interface Attribs1 {
@@ -25,9 +26,10 @@ interface Attribs1 {
2526
<test1 y={0} />; // Error, no property "y"
2627
<test1 y="foo" />; // Error, no property "y"
2728
<test1 x="32" />; // Error, "32" is not number
28-
// TODO attribute 'var' should be parseable
29-
// <test1 var="10" />; // Error, no 'var' property
29+
<test1 var="10" />; // Error, no 'var' property
3030

3131
<test2 />; // Error, missing reqd
3232
<test2 reqd={10} />; // Error, reqd is not string
3333

34+
// Should be OK
35+
<var var='var' />;

0 commit comments

Comments
 (0)