Merge pull request #2809 from Microsoft/noReservedWordsInBindingPatterns

Disallow reserved words for object binding pattern names
This commit is contained in:
Daniel Rosenwasser 2015-04-17 17:06:50 -07:00
commit 62036758a8
25 changed files with 157 additions and 19 deletions

View file

@ -6161,9 +6161,7 @@ module ts {
}
else {
Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment);
type = memberDecl.name.kind === SyntaxKind.ComputedPropertyName
? unknownType
: checkExpression(<Identifier>memberDecl.name, contextualMapper);
type = checkExpression((<ShorthandPropertyAssignment>memberDecl).name, contextualMapper);
}
typeFlags |= type.flags;
let prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name);
@ -8053,7 +8051,7 @@ module ts {
function checkNumericLiteral(node: LiteralExpression): Type {
// Grammar checking
checkGrammarNumbericLiteral(node);
checkGrammarNumericLiteral(node);
return numberType;
}
@ -12017,8 +12015,8 @@ module ts {
}
// GRAMMAR CHECKING
function isReservedwordInStrictMode(node: Identifier): boolean {
// Check that originalKeywordKind is less than LastFurtureReservedWord to see if an Identifier is a strict-mode reserved word
function isReservedWordInStrictMode(node: Identifier): boolean {
// Check that originalKeywordKind is less than LastFutureReservedWord to see if an Identifier is a strict-mode reserved word
return (node.parserContextFlags & ParserContextFlags.StrictMode) &&
(node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord && node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord);
}
@ -12063,7 +12061,7 @@ module ts {
function checkGrammarDeclarationNameInStrictMode(node: Declaration): boolean {
let name = node.name;
if (name && name.kind === SyntaxKind.Identifier && isReservedwordInStrictMode(<Identifier>name)) {
if (name && name.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(<Identifier>name)) {
let nameText = declarationNameToString(name);
switch (node.kind) {
case SyntaxKind.Parameter:
@ -12139,7 +12137,7 @@ module ts {
// The function takes an identifier itself or an expression which has SyntaxKind.Identifier.
function checkGrammarIdentifierInStrictMode(node: Expression | Identifier, nameText?: string): boolean {
if (node && node.kind === SyntaxKind.Identifier && isReservedwordInStrictMode(<Identifier>node)) {
if (node && node.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(<Identifier>node)) {
if (!nameText) {
nameText = declarationNameToString(<Identifier>node);
}
@ -12154,7 +12152,7 @@ module ts {
// The function takes an identifier when uses as a typeName in TypeReferenceNode
function checkGrammarTypeNameInStrictMode(node: Identifier): boolean {
if (node && node.kind === SyntaxKind.Identifier && isReservedwordInStrictMode(<Identifier>node)) {
if (node && node.kind === SyntaxKind.Identifier && isReservedWordInStrictMode(<Identifier>node)) {
let nameText = declarationNameToString(<Identifier>node);
// TODO (yuisu): Fix when module is a strict mode
@ -12606,7 +12604,7 @@ module ts {
// Grammar checking for computedPropertName and shorthandPropertyAssignment
checkGrammarForInvalidQuestionMark(prop,(<PropertyAssignment>prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
if (name.kind === SyntaxKind.NumericLiteral) {
checkGrammarNumbericLiteral(<Identifier>name);
checkGrammarNumericLiteral(<Identifier>name);
}
currentKind = Property;
}
@ -13158,7 +13156,7 @@ module ts {
}
}
function checkGrammarNumbericLiteral(node: Identifier): boolean {
function checkGrammarNumericLiteral(node: Identifier): boolean {
// Grammar checking
if (node.flags & NodeFlags.OctalLiteral) {
if (node.parserContextFlags & ParserContextFlags.StrictMode) {

View file

@ -3859,13 +3859,14 @@ module ts {
function parseObjectBindingElement(): BindingElement {
let node = <BindingElement>createNode(SyntaxKind.BindingElement);
// TODO(andersh): Handle computed properties
let id = parsePropertyName();
if (id.kind === SyntaxKind.Identifier && token !== SyntaxKind.ColonToken) {
node.name = <Identifier>id;
let tokenIsIdentifier = isIdentifier();
let propertyName = parsePropertyName();
if (tokenIsIdentifier && token !== SyntaxKind.ColonToken) {
node.name = <Identifier>propertyName;
}
else {
parseExpected(SyntaxKind.ColonToken);
node.propertyName = <Identifier>id;
node.propertyName = <Identifier>propertyName;
node.name = parseIdentifierOrPattern();
}
node.initializer = parseInitializer(/*inParameter*/ false);

View file

@ -389,7 +389,7 @@ module ts {
export interface Identifier extends PrimaryExpression {
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
}
export interface QualifiedName extends Node {

View file

@ -0,0 +1,8 @@
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers01.ts(2,13): error TS1005: ':' expected.
==== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers01.ts (1 errors) ====
var { while } = { while: 1 }
~
!!! error TS1005: ':' expected.

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers01.ts]
var { while } = { while: 1 }
//// [objectBindingPatternKeywordIdentifiers01.js]
var = { while: 1 }.while;

View file

@ -0,0 +1,11 @@
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers02.ts(2,14): error TS1003: Identifier expected.
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers02.ts(2,20): error TS1005: ':' expected.
==== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers02.ts (2 errors) ====
var { while: while } = { while: 1 }
~~~~~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ':' expected.

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers02.ts]
var { while: while } = { while: 1 }
//// [objectBindingPatternKeywordIdentifiers02.js]
var _a = { while: 1 }, = _a.while, = _a.while;

View file

@ -0,0 +1,8 @@
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers03.ts(2,15): error TS1005: ':' expected.
==== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers03.ts (1 errors) ====
var { "while" } = { while: 1 }
~
!!! error TS1005: ':' expected.

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers03.ts]
var { "while" } = { while: 1 }
//// [objectBindingPatternKeywordIdentifiers03.js]
var = { while: 1 }["while"];

View file

@ -0,0 +1,11 @@
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers04.ts(2,16): error TS1003: Identifier expected.
tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers04.ts(2,22): error TS1005: ':' expected.
==== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers04.ts (2 errors) ====
var { "while": while } = { while: 1 }
~~~~~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ':' expected.

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers04.ts]
var { "while": while } = { while: 1 }
//// [objectBindingPatternKeywordIdentifiers04.js]
var _a = { while: 1 }, = _a["while"], = _a.while;

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers05.ts]
var { as } = { as: 1 }
//// [objectBindingPatternKeywordIdentifiers05.js]
var as = { as: 1 }.as;

View file

@ -0,0 +1,6 @@
=== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers05.ts ===
var { as } = { as: 1 }
>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers05.ts, 1, 5))
>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers05.ts, 1, 14))

View file

@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers05.ts ===
var { as } = { as: 1 }
>as : number
>{ as: 1 } : { as: number; }
>as : number
>1 : number

View file

@ -0,0 +1,6 @@
//// [objectBindingPatternKeywordIdentifiers06.ts]
var { as: as } = { as: 1 }
//// [objectBindingPatternKeywordIdentifiers06.js]
var as = { as: 1 }.as;

View file

@ -0,0 +1,6 @@
=== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers06.ts ===
var { as: as } = { as: 1 }
>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 5))
>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 18))

View file

@ -0,0 +1,9 @@
=== tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers06.ts ===
var { as: as } = { as: 1 }
>as : any
>as : number
>{ as: 1 } : { as: number; }
>as : number
>1 : number

View file

@ -15,6 +15,14 @@ tests/cases/compiler/reservedWords2.ts(5,10): error TS1003: Identifier expected.
tests/cases/compiler/reservedWords2.ts(5,18): error TS1005: '=>' expected.
tests/cases/compiler/reservedWords2.ts(6,7): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(6,8): error TS1003: Identifier expected.
tests/cases/compiler/reservedWords2.ts(7,11): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(7,11): error TS1005: ':' expected.
tests/cases/compiler/reservedWords2.ts(7,19): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(7,19): error TS1005: ':' expected.
tests/cases/compiler/reservedWords2.ts(8,10): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(8,10): error TS1005: ':' expected.
tests/cases/compiler/reservedWords2.ts(8,30): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(8,30): error TS1005: ':' expected.
tests/cases/compiler/reservedWords2.ts(9,6): error TS1181: Array element destructuring pattern expected.
tests/cases/compiler/reservedWords2.ts(9,14): error TS1005: ';' expected.
tests/cases/compiler/reservedWords2.ts(9,18): error TS1005: '(' expected.
@ -23,7 +31,7 @@ tests/cases/compiler/reservedWords2.ts(10,5): error TS2300: Duplicate identifier
tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected.
==== tests/cases/compiler/reservedWords2.ts (23 errors) ====
==== tests/cases/compiler/reservedWords2.ts (31 errors) ====
import while = require("dfdf");
~~~~~~
!!! error TS1148: Cannot compile external modules unless the '--module' flag is provided.
@ -65,7 +73,23 @@ tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected.
~~~~
!!! error TS1003: Identifier expected.
var {while, return} = { while: 1, return: 2 };
!!! error TS2300: Duplicate identifier '(Missing)'.
~
!!! error TS1005: ':' expected.
!!! error TS2300: Duplicate identifier '(Missing)'.
~
!!! error TS1005: ':' expected.
var {this, switch: { continue} } = { this: 1, switch: { continue: 2 }};
!!! error TS2300: Duplicate identifier '(Missing)'.
~
!!! error TS1005: ':' expected.
!!! error TS2300: Duplicate identifier '(Missing)'.
~
!!! error TS1005: ':' expected.
var [debugger, if] = [1, 2];
~~~~~~~~
!!! error TS1181: Array element destructuring pattern expected.

View file

@ -24,8 +24,8 @@ typeof ;
10;
throw function () { };
void {};
var _a = { while: 1, return: 2 }, while = _a.while, return = _a.return;
var _b = { this: 1, switch: { continue: 2 } }, this = _b.this, continue = _b.switch.continue;
var _a = { while: 1, return: 2 }, = _a.while, = _a.return;
var _b = { this: 1, switch: { continue: 2 } }, = _b.this, = _b.switch.continue;
var _c = void 0;
debugger;
if ()

View file

@ -0,0 +1,2 @@

var { while } = { while: 1 }

View file

@ -0,0 +1,2 @@

var { while: while } = { while: 1 }

View file

@ -0,0 +1,2 @@

var { "while" } = { while: 1 }

View file

@ -0,0 +1,2 @@

var { "while": while } = { while: 1 }

View file

@ -0,0 +1,2 @@

var { as } = { as: 1 }

View file

@ -0,0 +1,2 @@

var { as: as } = { as: 1 }