From afb035631a104d1016a869719a42f93c479ba4e8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 19 Nov 2014 00:19:26 -0800 Subject: [PATCH] Move strict check for binary expressions to grammar checker. --- src/compiler/parser.ts | 90 +++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 25b6f11fa5b..c10adae271b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2043,12 +2043,7 @@ module ts { // Now see if we might be in cases '2' or '3'. // If the expression was a LHS expression, and we have an assignment operator, then // we're in '2' or '3'. Consume the assignment and return. - if (isLeftHandSideExpression(expr) && isAssignmentOperator()) { - if (isInStrictMode && isEvalOrArgumentsIdentifier(expr)) { - // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) - reportInvalidUseInStrictMode(expr); - } + if (isLeftHandSideExpression(expr) && isAssignmentOperator(token)) { var operator = token; nextToken(); return makeBinaryExpression(expr, operator, parseAssignmentExpression(noIn)); @@ -2058,37 +2053,6 @@ module ts { return expr; } - function isLeftHandSideExpression(expr: Expression): boolean { - if (expr) { - switch (expr.kind) { - case SyntaxKind.PropertyAccess: - case SyntaxKind.IndexedAccess: - case SyntaxKind.NewExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.ArrayLiteral: - case SyntaxKind.ParenExpression: - case SyntaxKind.ObjectLiteral: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Identifier: - case SyntaxKind.Missing: - case SyntaxKind.RegularExpressionLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateExpression: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.SuperKeyword: - return true; - } - } - - return false; - } - function parseSimpleArrowFunctionExpression(identifier: Identifier): Expression { Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); parseExpected(SyntaxKind.EqualsGreaterThanToken); @@ -2269,10 +2233,6 @@ module ts { return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /* name */ undefined, sig, body); } - function isAssignmentOperator(): boolean { - return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment; - } - function parseConditionalExpression(noIn?: boolean): Expression { var expr = parseBinaryExpression(noIn); while (parseOptional(SyntaxKind.QuestionToken)) { @@ -4033,6 +3993,41 @@ module ts { return file; } + function isLeftHandSideExpression(expr: Expression): boolean { + if (expr) { + switch (expr.kind) { + case SyntaxKind.PropertyAccess: + case SyntaxKind.IndexedAccess: + case SyntaxKind.NewExpression: + case SyntaxKind.CallExpression: + case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.ArrayLiteral: + case SyntaxKind.ParenExpression: + case SyntaxKind.ObjectLiteral: + case SyntaxKind.FunctionExpression: + case SyntaxKind.Identifier: + case SyntaxKind.Missing: + case SyntaxKind.RegularExpressionLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateExpression: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.ThisKeyword: + case SyntaxKind.TrueKeyword: + case SyntaxKind.SuperKeyword: + return true; + } + } + + return false; + } + + function isAssignmentOperator(token: SyntaxKind): boolean { + return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment; + } + function checkGrammar(sourceText: string, languageVersion: ScriptTarget, file: SourceFileInternal) { var syntacticDiagnostics = file._syntacticDiagnostics; @@ -4069,6 +4064,7 @@ module ts { // No grammar errors on any of our children. Check this node for grammar errors. switch (node.kind) { case SyntaxKind.ArrowFunction: return visitArrowFunction(node); + case SyntaxKind.BinaryExpression: return visitBinaryExpression(node); case SyntaxKind.CallSignature: return visitCallSignature(node); case SyntaxKind.CatchBlock: return visitCatchBlock(node); case SyntaxKind.Constructor: return visitConstructor(node); @@ -4118,6 +4114,18 @@ module ts { checkParameterList(node.parameters); } + function visitBinaryExpression(node: BinaryExpression) { + if (node.flags & NodeFlags.ParsedInStrictMode) { + if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operator)) { + if (isEvalOrArgumentsIdentifier(node.left)) { + // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an + // Assignment operator(11.13) or of a PostfixExpression(11.3) + reportInvalidUseInStrictMode(node.left); + } + } + } + } + function visitCallSignature(node: ConstructorDeclaration) { checkTypeParameterList(node.typeParameters) || checkParameterList(node.parameters);