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 {
|
||||
return createIdentifier(isIdentifierOrKeyword());
|
||||
return createIdentifier(tokenIsIdentifierOrKeyword(token));
|
||||
}
|
||||
|
||||
function isLiteralPropertyName(): boolean {
|
||||
return isIdentifierOrKeyword() ||
|
||||
return tokenIsIdentifierOrKeyword(token) ||
|
||||
token === SyntaxKind.StringLiteral ||
|
||||
token === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
@ -1086,7 +1086,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isSimplePropertyName() {
|
||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || isIdentifierOrKeyword();
|
||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || tokenIsIdentifierOrKeyword(token);
|
||||
}
|
||||
|
||||
function parseComputedPropertyName(): ComputedPropertyName {
|
||||
|
@ -1213,9 +1213,9 @@ namespace ts {
|
|||
case ParsingContext.HeritageClauses:
|
||||
return isHeritageClause();
|
||||
case ParsingContext.ImportOrExportSpecifiers:
|
||||
return isIdentifierOrKeyword();
|
||||
return tokenIsIdentifierOrKeyword(token);
|
||||
case ParsingContext.JsxAttributes:
|
||||
return isIdentifierOrKeyword() || token === SyntaxKind.OpenBraceToken;
|
||||
return tokenIsIdentifierOrKeyword(token) || token === SyntaxKind.OpenBraceToken;
|
||||
case ParsingContext.JsxChildren:
|
||||
return true;
|
||||
case ParsingContext.JSDocFunctionParameters:
|
||||
|
@ -1254,7 +1254,7 @@ namespace ts {
|
|||
|
||||
function nextTokenIsIdentifierOrKeyword() {
|
||||
nextToken();
|
||||
return isIdentifierOrKeyword();
|
||||
return tokenIsIdentifierOrKeyword(token);
|
||||
}
|
||||
|
||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||
|
@ -1824,7 +1824,7 @@ namespace ts {
|
|||
// the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
|
||||
// In the first case though, ASI will not take effect because there is not a
|
||||
// line terminator after the identifier or keyword.
|
||||
if (scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword()) {
|
||||
if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token)) {
|
||||
let matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
|
||||
|
||||
if (matchesPattern) {
|
||||
|
@ -2282,7 +2282,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (isIdentifierOrKeyword()) {
|
||||
if (tokenIsIdentifierOrKeyword(token)) {
|
||||
return parsePropertyOrMethodSignature();
|
||||
}
|
||||
}
|
||||
|
@ -4101,13 +4101,9 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function isIdentifierOrKeyword() {
|
||||
return token >= SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrKeywordOnSameLine() {
|
||||
nextToken();
|
||||
return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak();
|
||||
return tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function nextTokenIsFunctionKeywordOnSameLine() {
|
||||
|
@ -4117,7 +4113,7 @@ namespace ts {
|
|||
|
||||
function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
|
||||
nextToken();
|
||||
return (isIdentifierOrKeyword() || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
return (tokenIsIdentifierOrKeyword(token) || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function isDeclaration(): boolean {
|
||||
|
@ -4170,7 +4166,7 @@ namespace ts {
|
|||
case SyntaxKind.ImportKeyword:
|
||||
nextToken();
|
||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
|
||||
token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword();
|
||||
token === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token);
|
||||
case SyntaxKind.ExportKeyword:
|
||||
nextToken();
|
||||
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
|
||||
// the [ token can start an index signature or a computed property name
|
||||
if (isIdentifierOrKeyword() ||
|
||||
if (tokenIsIdentifierOrKeyword(token) ||
|
||||
token === SyntaxKind.StringLiteral ||
|
||||
token === SyntaxKind.NumericLiteral ||
|
||||
token === SyntaxKind.AsteriskToken ||
|
||||
|
@ -5320,7 +5316,7 @@ namespace ts {
|
|||
return true;
|
||||
}
|
||||
|
||||
return isIdentifierOrKeyword();
|
||||
return tokenIsIdentifierOrKeyword(token);
|
||||
}
|
||||
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
||||
|
|
|
@ -6,6 +6,11 @@ namespace ts {
|
|||
(message: DiagnosticMessage, length: number): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean {
|
||||
return token >= SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
export interface Scanner {
|
||||
getStartPos(): number;
|
||||
getToken(): SyntaxKind;
|
||||
|
@ -1590,7 +1595,7 @@ namespace ts {
|
|||
// Scans a JSX identifier; these differ from normal identifiers in that
|
||||
// they allow dashes
|
||||
function scanJsxIdentifier(): SyntaxKind {
|
||||
if (token === SyntaxKind.Identifier) {
|
||||
if (tokenIsIdentifierOrKeyword(token)) {
|
||||
let firstCharPosition = pos;
|
||||
while (pos < end) {
|
||||
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