Merge pull request #4705 from Microsoft/keywordInJsxIdentifier
allow jsx identifiers to start with keywords
This commit is contained in:
commit
c90276f73c
|
@ -1058,11 +1058,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseIdentifierName(): Identifier {
|
function parseIdentifierName(): Identifier {
|
||||||
return createIdentifier(isIdentifierOrKeyword());
|
return createIdentifier(tokenIsIdentifierOrKeyword(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLiteralPropertyName(): boolean {
|
function isLiteralPropertyName(): boolean {
|
||||||
return isIdentifierOrKeyword() ||
|
return tokenIsIdentifierOrKeyword(token) ||
|
||||||
token === SyntaxKind.StringLiteral ||
|
token === SyntaxKind.StringLiteral ||
|
||||||
token === SyntaxKind.NumericLiteral;
|
token === SyntaxKind.NumericLiteral;
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1086,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSimplePropertyName() {
|
function isSimplePropertyName() {
|
||||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || isIdentifierOrKeyword();
|
return token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || tokenIsIdentifierOrKeyword(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseComputedPropertyName(): ComputedPropertyName {
|
function parseComputedPropertyName(): ComputedPropertyName {
|
||||||
|
@ -1213,9 +1213,9 @@ namespace ts {
|
||||||
case ParsingContext.HeritageClauses:
|
case ParsingContext.HeritageClauses:
|
||||||
return isHeritageClause();
|
return isHeritageClause();
|
||||||
case ParsingContext.ImportOrExportSpecifiers:
|
case ParsingContext.ImportOrExportSpecifiers:
|
||||||
return isIdentifierOrKeyword();
|
return tokenIsIdentifierOrKeyword(token);
|
||||||
case ParsingContext.JsxAttributes:
|
case ParsingContext.JsxAttributes:
|
||||||
return isIdentifierOrKeyword() || token === SyntaxKind.OpenBraceToken;
|
return tokenIsIdentifierOrKeyword(token) || token === SyntaxKind.OpenBraceToken;
|
||||||
case ParsingContext.JsxChildren:
|
case ParsingContext.JsxChildren:
|
||||||
return true;
|
return true;
|
||||||
case ParsingContext.JSDocFunctionParameters:
|
case ParsingContext.JSDocFunctionParameters:
|
||||||
|
@ -1254,7 +1254,7 @@ namespace ts {
|
||||||
|
|
||||||
function nextTokenIsIdentifierOrKeyword() {
|
function nextTokenIsIdentifierOrKeyword() {
|
||||||
nextToken();
|
nextToken();
|
||||||
return isIdentifierOrKeyword();
|
return tokenIsIdentifierOrKeyword(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||||
|
@ -1824,7 +1824,7 @@ namespace ts {
|
||||||
// the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
|
// the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
|
||||||
// In the first case though, ASI will not take effect because there is not a
|
// In the first case though, ASI will not take effect because there is not a
|
||||||
// line terminator after the identifier or keyword.
|
// line terminator after the identifier or keyword.
|
||||||
if (scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword()) {
|
if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token)) {
|
||||||
let matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
|
let matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
|
||||||
|
|
||||||
if (matchesPattern) {
|
if (matchesPattern) {
|
||||||
|
@ -2282,7 +2282,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIdentifierOrKeyword()) {
|
if (tokenIsIdentifierOrKeyword(token)) {
|
||||||
return parsePropertyOrMethodSignature();
|
return parsePropertyOrMethodSignature();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4101,13 +4101,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isIdentifierOrKeyword() {
|
|
||||||
return token >= SyntaxKind.Identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
function nextTokenIsIdentifierOrKeywordOnSameLine() {
|
function nextTokenIsIdentifierOrKeywordOnSameLine() {
|
||||||
nextToken();
|
nextToken();
|
||||||
return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak();
|
return tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextTokenIsFunctionKeywordOnSameLine() {
|
function nextTokenIsFunctionKeywordOnSameLine() {
|
||||||
|
@ -4117,7 +4113,7 @@ namespace ts {
|
||||||
|
|
||||||
function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
|
function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
|
||||||
nextToken();
|
nextToken();
|
||||||
return (isIdentifierOrKeyword() || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak();
|
return (tokenIsIdentifierOrKeyword(token) || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeclaration(): boolean {
|
function isDeclaration(): boolean {
|
||||||
|
@ -4170,7 +4166,7 @@ namespace ts {
|
||||||
case SyntaxKind.ImportKeyword:
|
case SyntaxKind.ImportKeyword:
|
||||||
nextToken();
|
nextToken();
|
||||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
|
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
|
||||||
token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword();
|
token === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token);
|
||||||
case SyntaxKind.ExportKeyword:
|
case SyntaxKind.ExportKeyword:
|
||||||
nextToken();
|
nextToken();
|
||||||
if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken ||
|
if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken ||
|
||||||
|
@ -4777,7 +4773,7 @@ namespace ts {
|
||||||
|
|
||||||
// It is very important that we check this *after* checking indexers because
|
// It is very important that we check this *after* checking indexers because
|
||||||
// the [ token can start an index signature or a computed property name
|
// the [ token can start an index signature or a computed property name
|
||||||
if (isIdentifierOrKeyword() ||
|
if (tokenIsIdentifierOrKeyword(token) ||
|
||||||
token === SyntaxKind.StringLiteral ||
|
token === SyntaxKind.StringLiteral ||
|
||||||
token === SyntaxKind.NumericLiteral ||
|
token === SyntaxKind.NumericLiteral ||
|
||||||
token === SyntaxKind.AsteriskToken ||
|
token === SyntaxKind.AsteriskToken ||
|
||||||
|
@ -5320,7 +5316,7 @@ namespace ts {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isIdentifierOrKeyword();
|
return tokenIsIdentifierOrKeyword(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
||||||
|
|
|
@ -6,6 +6,11 @@ namespace ts {
|
||||||
(message: DiagnosticMessage, length: number): void;
|
(message: DiagnosticMessage, length: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @internal */
|
||||||
|
export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean {
|
||||||
|
return token >= SyntaxKind.Identifier;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Scanner {
|
export interface Scanner {
|
||||||
getStartPos(): number;
|
getStartPos(): number;
|
||||||
getToken(): SyntaxKind;
|
getToken(): SyntaxKind;
|
||||||
|
@ -1590,7 +1595,7 @@ namespace ts {
|
||||||
// Scans a JSX identifier; these differ from normal identifiers in that
|
// Scans a JSX identifier; these differ from normal identifiers in that
|
||||||
// they allow dashes
|
// they allow dashes
|
||||||
function scanJsxIdentifier(): SyntaxKind {
|
function scanJsxIdentifier(): SyntaxKind {
|
||||||
if (token === SyntaxKind.Identifier) {
|
if (tokenIsIdentifierOrKeyword(token)) {
|
||||||
let firstCharPosition = pos;
|
let firstCharPosition = pos;
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
let ch = text.charCodeAt(pos);
|
let ch = text.charCodeAt(pos);
|
||||||
|
|
14
tests/baselines/reference/keywordInJsxIdentifier.js
Normal file
14
tests/baselines/reference/keywordInJsxIdentifier.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//// [keywordInJsxIdentifier.tsx]
|
||||||
|
|
||||||
|
declare var React: any;
|
||||||
|
<foo class-id/>;
|
||||||
|
<foo class/>;
|
||||||
|
<foo class-id="1"/>;
|
||||||
|
<foo class="1"/>;
|
||||||
|
|
||||||
|
|
||||||
|
//// [keywordInJsxIdentifier.js]
|
||||||
|
React.createElement("foo", {"class-id": true});
|
||||||
|
React.createElement("foo", {"class": true});
|
||||||
|
React.createElement("foo", {"class-id": "1"});
|
||||||
|
React.createElement("foo", {"class": "1"});
|
17
tests/baselines/reference/keywordInJsxIdentifier.symbols
Normal file
17
tests/baselines/reference/keywordInJsxIdentifier.symbols
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
=== tests/cases/compiler/keywordInJsxIdentifier.tsx ===
|
||||||
|
|
||||||
|
declare var React: any;
|
||||||
|
>React : Symbol(React, Decl(keywordInJsxIdentifier.tsx, 1, 11))
|
||||||
|
|
||||||
|
<foo class-id/>;
|
||||||
|
>class-id : Symbol(unknown)
|
||||||
|
|
||||||
|
<foo class/>;
|
||||||
|
>class : Symbol(unknown)
|
||||||
|
|
||||||
|
<foo class-id="1"/>;
|
||||||
|
>class-id : Symbol(unknown)
|
||||||
|
|
||||||
|
<foo class="1"/>;
|
||||||
|
>class : Symbol(unknown)
|
||||||
|
|
25
tests/baselines/reference/keywordInJsxIdentifier.types
Normal file
25
tests/baselines/reference/keywordInJsxIdentifier.types
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
=== tests/cases/compiler/keywordInJsxIdentifier.tsx ===
|
||||||
|
|
||||||
|
declare var React: any;
|
||||||
|
>React : any
|
||||||
|
|
||||||
|
<foo class-id/>;
|
||||||
|
><foo class-id/> : any
|
||||||
|
>foo : any
|
||||||
|
>class-id : any
|
||||||
|
|
||||||
|
<foo class/>;
|
||||||
|
><foo class/> : any
|
||||||
|
>foo : any
|
||||||
|
>class : any
|
||||||
|
|
||||||
|
<foo class-id="1"/>;
|
||||||
|
><foo class-id="1"/> : any
|
||||||
|
>foo : any
|
||||||
|
>class-id : any
|
||||||
|
|
||||||
|
<foo class="1"/>;
|
||||||
|
><foo class="1"/> : any
|
||||||
|
>foo : any
|
||||||
|
>class : any
|
||||||
|
|
7
tests/cases/compiler/keywordInJsxIdentifier.tsx
Normal file
7
tests/cases/compiler/keywordInJsxIdentifier.tsx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//@jsx: react
|
||||||
|
|
||||||
|
declare var React: any;
|
||||||
|
<foo class-id/>;
|
||||||
|
<foo class/>;
|
||||||
|
<foo class-id="1"/>;
|
||||||
|
<foo class="1"/>;
|
Loading…
Reference in a new issue