diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 350b9d450b..330ad05518 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -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) {
diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts
index 199e7e9b63..82fbc8c2a5 100644
--- a/src/compiler/scanner.ts
+++ b/src/compiler/scanner.ts
@@ -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);
diff --git a/tests/baselines/reference/keywordInJsxIdentifier.js b/tests/baselines/reference/keywordInJsxIdentifier.js
new file mode 100644
index 0000000000..677a79138e
--- /dev/null
+++ b/tests/baselines/reference/keywordInJsxIdentifier.js
@@ -0,0 +1,14 @@
+//// [keywordInJsxIdentifier.tsx]
+
+declare var React: any;
+;
+;
+;
+;
+
+
+//// [keywordInJsxIdentifier.js]
+React.createElement("foo", {"class-id": true});
+React.createElement("foo", {"class": true});
+React.createElement("foo", {"class-id": "1"});
+React.createElement("foo", {"class": "1"});
diff --git a/tests/baselines/reference/keywordInJsxIdentifier.symbols b/tests/baselines/reference/keywordInJsxIdentifier.symbols
new file mode 100644
index 0000000000..874d7801a7
--- /dev/null
+++ b/tests/baselines/reference/keywordInJsxIdentifier.symbols
@@ -0,0 +1,17 @@
+=== tests/cases/compiler/keywordInJsxIdentifier.tsx ===
+
+declare var React: any;
+>React : Symbol(React, Decl(keywordInJsxIdentifier.tsx, 1, 11))
+
+;
+>class-id : Symbol(unknown)
+
+;
+>class : Symbol(unknown)
+
+;
+>class-id : Symbol(unknown)
+
+;
+>class : Symbol(unknown)
+
diff --git a/tests/baselines/reference/keywordInJsxIdentifier.types b/tests/baselines/reference/keywordInJsxIdentifier.types
new file mode 100644
index 0000000000..745fa5998b
--- /dev/null
+++ b/tests/baselines/reference/keywordInJsxIdentifier.types
@@ -0,0 +1,25 @@
+=== tests/cases/compiler/keywordInJsxIdentifier.tsx ===
+
+declare var React: any;
+>React : any
+
+;
+> : any
+>foo : any
+>class-id : any
+
+;
+> : any
+>foo : any
+>class : any
+
+;
+> : any
+>foo : any
+>class-id : any
+
+;
+> : any
+>foo : any
+>class : any
+
diff --git a/tests/cases/compiler/keywordInJsxIdentifier.tsx b/tests/cases/compiler/keywordInJsxIdentifier.tsx
new file mode 100644
index 0000000000..ce858edae5
--- /dev/null
+++ b/tests/cases/compiler/keywordInJsxIdentifier.tsx
@@ -0,0 +1,7 @@
+//@jsx: react
+
+declare var React: any;
+;
+;
+;
+;