From e5c3661e304ad75eb54178bc162b049bed36936a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 18 Nov 2014 22:03:07 -0800 Subject: [PATCH] Move postfix/prefix checks to the grammar check. --- src/compiler/parser.ts | 49 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4e9f9488111..302635aaff9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2373,21 +2373,7 @@ module ts { case SyntaxKind.MinusMinusToken: var operator = token; nextToken(); - var operand = parseUnaryExpression(); - if (isInStrictMode) { - // The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression - // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator - if ((operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken) && isEvalOrArgumentsIdentifier(operand)) { - reportInvalidUseInStrictMode(operand); - } - else if (operator === SyntaxKind.DeleteKeyword && operand.kind === SyntaxKind.Identifier) { - // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its - // UnaryExpression is a direct reference to a variable, function argument, or function name - grammarErrorOnNode(operand, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode); - } - } - return makeUnaryExpression(SyntaxKind.PrefixOperator, pos, operator, operand); + return makeUnaryExpression(SyntaxKind.PrefixOperator, pos, operator, parseUnaryExpression()); case SyntaxKind.LessThanToken: return parseTypeAssertion(); } @@ -2408,12 +2394,6 @@ module ts { Debug.assert(isLeftHandSideExpression(expr)); if ((token === SyntaxKind.PlusPlusToken || token === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { - // The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression - // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. - if (isInStrictMode && isEvalOrArgumentsIdentifier(expr)) { - reportInvalidUseInStrictMode(expr); - } var operator = token; nextToken(); expr = makeUnaryExpression(SyntaxKind.PostfixOperator, expr.pos, operator, expr); @@ -4202,6 +4182,8 @@ module ts { case SyntaxKind.Method: return visitMethod(node); case SyntaxKind.ObjectLiteral: return visitObjectLiteral(node); case SyntaxKind.Parameter: return visitParameter(node); + case SyntaxKind.PostfixOperator: return visitPostfixOperator(node); + case SyntaxKind.PrefixOperator: return visitPrefixOperator(node); case SyntaxKind.SetAccessor: return visitSetAccessor(node); case SyntaxKind.TaggedTemplateExpression: return visitTaggedTemplateExpression(node); } @@ -4415,6 +4397,31 @@ module ts { } } + function visitPostfixOperator(node: UnaryExpression) { + // The identifier eval or arguments may not appear as the LeftHandSideExpression of an + // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression + // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. + if (node.flags & NodeFlags.ParsedInStrictMode && isEvalOrArgumentsIdentifier(node.operand)) { + reportInvalidUseInStrictMode(node.operand); + } + } + + function visitPrefixOperator(node: UnaryExpression) { + if (node.flags & NodeFlags.ParsedInStrictMode) { + // The identifier eval or arguments may not appear as the LeftHandSideExpression of an + // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression + // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator + if ((node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) && isEvalOrArgumentsIdentifier(node.operand)) { + reportInvalidUseInStrictMode(node.operand); + } + else if (node.operator === SyntaxKind.DeleteKeyword && node.operand.kind === SyntaxKind.Identifier) { + // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its + // UnaryExpression is a direct reference to a variable, function argument, or function name + grammarErrorOnNode(node.operand, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode); + } + } + } + function visitSetAccessor(node: MethodDeclaration) { checkParameterList(node.parameters) || checkAccessor(node);