Skip to content

Commit fc22936

Browse files
Include the binary expression's operator in the AST.
1 parent 5c1ef11 commit fc22936

17 files changed

Lines changed: 78 additions & 78 deletions

src/compiler/checker.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,7 +3409,7 @@ module ts {
34093409
return isContextSensitive((<ConditionalExpression>node).whenTrue) ||
34103410
isContextSensitive((<ConditionalExpression>node).whenFalse);
34113411
case SyntaxKind.BinaryExpression:
3412-
return (<BinaryExpression>node).operator === SyntaxKind.BarBarToken &&
3412+
return (<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken &&
34133413
(isContextSensitive((<BinaryExpression>node).left) || isContextSensitive((<BinaryExpression>node).right));
34143414
case SyntaxKind.PropertyAssignment:
34153415
return isContextSensitive((<PropertyAssignment>node).initializer);
@@ -4591,7 +4591,7 @@ module ts {
45914591
return links.assignmentChecks[symbol.id] = isAssignedIn(node);
45924592

45934593
function isAssignedInBinaryExpression(node: BinaryExpression) {
4594-
if (node.operator >= SyntaxKind.FirstAssignment && node.operator <= SyntaxKind.LastAssignment) {
4594+
if (node.operatorToken.kind >= SyntaxKind.FirstAssignment && node.operatorToken.kind <= SyntaxKind.LastAssignment) {
45954595
var n = node.left;
45964596
while (n.kind === SyntaxKind.ParenthesizedExpression) {
45974597
n = (<ParenthesizedExpression>n).expression;
@@ -4724,10 +4724,10 @@ module ts {
47244724
case SyntaxKind.BinaryExpression:
47254725
// In the right operand of an && or ||, narrow based on left operand
47264726
if (child === (<BinaryExpression>node).right) {
4727-
if ((<BinaryExpression>node).operator === SyntaxKind.AmpersandAmpersandToken) {
4727+
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
47284728
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ true);
47294729
}
4730-
else if ((<BinaryExpression>node).operator === SyntaxKind.BarBarToken) {
4730+
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken) {
47314731
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ false);
47324732
}
47334733
}
@@ -4765,7 +4765,7 @@ module ts {
47654765
return type;
47664766
}
47674767
var typeInfo = primitiveTypeInfo[right.text];
4768-
if (expr.operator === SyntaxKind.ExclamationEqualsEqualsToken) {
4768+
if (expr.operatorToken.kind === SyntaxKind.ExclamationEqualsEqualsToken) {
47694769
assumeTrue = !assumeTrue;
47704770
}
47714771
if (assumeTrue) {
@@ -4855,7 +4855,7 @@ module ts {
48554855
case SyntaxKind.ParenthesizedExpression:
48564856
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
48574857
case SyntaxKind.BinaryExpression:
4858-
var operator = (<BinaryExpression>expr).operator;
4858+
var operator = (<BinaryExpression>expr).operatorToken.kind;
48594859
if (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
48604860
return narrowTypeByEquality(type, <BinaryExpression>expr, assumeTrue);
48614861
}
@@ -5202,7 +5202,7 @@ module ts {
52025202

52035203
function getContextualTypeForBinaryOperand(node: Expression): Type {
52045204
var binaryExpression = <BinaryExpression>node.parent;
5205-
var operator = binaryExpression.operator;
5205+
var operator = binaryExpression.operatorToken.kind;
52065206
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
52075207
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
52085208
if (node === binaryExpression.right) {
@@ -5452,7 +5452,7 @@ module ts {
54525452
// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'.
54535453
function isAssignmentTarget(node: Node): boolean {
54545454
var parent = node.parent;
5455-
if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operator === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node) {
5455+
if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node) {
54565456
return true;
54575457
}
54585458
if (parent.kind === SyntaxKind.PropertyAssignment) {
@@ -7108,7 +7108,7 @@ module ts {
71087108
}
71097109

71107110
function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
7111-
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operator === SyntaxKind.EqualsToken) {
7111+
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
71127112
checkBinaryExpression(<BinaryExpression>target, contextualMapper);
71137113
target = (<BinaryExpression>target).left;
71147114
}
@@ -7131,13 +7131,13 @@ module ts {
71317131

71327132
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
71337133
// Grammar checking
7134-
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operator)) {
7134+
if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
71357135
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
71367136
// Assignment operator(11.13) or of a PostfixExpression(11.3)
71377137
checkGrammarEvalOrArgumentsInStrictMode(node, <Identifier>node.left);
71387138
}
71397139

7140-
var operator = node.operator;
7140+
var operator = node.operatorToken.kind;
71417141
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
71427142
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
71437143
}
@@ -7178,8 +7178,8 @@ module ts {
71787178
// try and return them a helpful suggestion
71797179
if ((leftType.flags & TypeFlags.Boolean) &&
71807180
(rightType.flags & TypeFlags.Boolean) &&
7181-
(suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) {
7182-
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator));
7181+
(suggestedOperator = getSuggestedBooleanOperator(node.operatorToken.kind)) !== undefined) {
7182+
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operatorToken.kind), tokenToString(suggestedOperator));
71837183
}
71847184
else {
71857185
// otherwise just check each operand separately and report errors as normal
@@ -7312,7 +7312,7 @@ module ts {
73127312
}
73137313

73147314
function reportOperatorError() {
7315-
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operator), typeToString(leftType), typeToString(rightType));
7315+
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType));
73167316
}
73177317
}
73187318

@@ -9252,7 +9252,7 @@ module ts {
92529252
if (right === undefined) {
92539253
return undefined;
92549254
}
9255-
switch ((<BinaryExpression>e).operator) {
9255+
switch ((<BinaryExpression>e).operatorToken.kind) {
92569256
case SyntaxKind.BarToken: return left | right;
92579257
case SyntaxKind.AmpersandToken: return left & right;
92589258
case SyntaxKind.GreaterThanGreaterThanToken: return left >> right;
@@ -10830,7 +10830,7 @@ module ts {
1083010830
if (languageVersion < ScriptTarget.ES6) {
1083110831
return grammarErrorOnNode(node, Diagnostics.Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher);
1083210832
}
10833-
else if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>computedPropertyName.expression).operator === SyntaxKind.CommaToken) {
10833+
else if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>computedPropertyName.expression).operatorToken.kind === SyntaxKind.CommaToken) {
1083410834
return grammarErrorOnNode(computedPropertyName.expression, Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
1083510835
}
1083610836
}

src/compiler/emitter.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,7 +2252,7 @@ module ts {
22522252
// spread ('...') unary operators that are anticipated for ES6.
22532253
switch (expression.kind) {
22542254
case SyntaxKind.BinaryExpression:
2255-
switch ((<BinaryExpression>expression).operator) {
2255+
switch ((<BinaryExpression>expression).operatorToken.kind) {
22562256
case SyntaxKind.AsteriskToken:
22572257
case SyntaxKind.SlashToken:
22582258
case SyntaxKind.PercentToken:
@@ -2773,14 +2773,14 @@ module ts {
27732773
}
27742774

27752775
function emitBinaryExpression(node: BinaryExpression) {
2776-
if (languageVersion < ScriptTarget.ES6 && node.operator === SyntaxKind.EqualsToken &&
2776+
if (languageVersion < ScriptTarget.ES6 && node.operatorToken.kind === SyntaxKind.EqualsToken &&
27772777
(node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
27782778
emitDestructuring(node);
27792779
}
27802780
else {
27812781
emit(node.left);
2782-
if (node.operator !== SyntaxKind.CommaToken) write(" ");
2783-
write(tokenToString(node.operator));
2782+
if (node.operatorToken.kind !== SyntaxKind.CommaToken) write(" ");
2783+
write(tokenToString(node.operatorToken.kind));
27842784
write(" ");
27852785
emit(node.right);
27862786
}
@@ -3122,7 +3122,7 @@ module ts {
31223122
// Return the expression 'value === void 0 ? defaultValue : value'
31233123
var equals = <BinaryExpression>createNode(SyntaxKind.BinaryExpression);
31243124
equals.left = value;
3125-
equals.operator = SyntaxKind.EqualsEqualsEqualsToken;
3125+
equals.operatorToken = createNode(SyntaxKind.EqualsEqualsEqualsToken);
31263126
equals.right = createVoidZero();
31273127
var cond = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression);
31283128
cond.condition = equals;
@@ -3205,7 +3205,7 @@ module ts {
32053205
}
32063206

32073207
function emitDestructuringAssignment(target: Expression, value: Expression) {
3208-
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operator === SyntaxKind.EqualsToken) {
3208+
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
32093209
value = createDefaultValueCheck(value,(<BinaryExpression>target).right);
32103210
target = (<BinaryExpression>target).left;
32113211
}

src/compiler/parser.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ module ts {
152152
return visitNode(cbNode, (<PostfixUnaryExpression>node).operand);
153153
case SyntaxKind.BinaryExpression:
154154
return visitNode(cbNode, (<BinaryExpression>node).left) ||
155+
visitNode(cbNode, (<BinaryExpression>node).operatorToken) ||
155156
visitNode(cbNode, (<BinaryExpression>node).right);
156157
case SyntaxKind.ConditionalExpression:
157158
return visitNode(cbNode, (<ConditionalExpression>node).condition) ||
@@ -1311,6 +1312,12 @@ module ts {
13111312
return undefined;
13121313
}
13131314

1315+
function parseTokenNode<T extends Node>(): T {
1316+
var node = <T>createNode(token);
1317+
nextToken();
1318+
return finishNode(node);
1319+
}
1320+
13141321
function canParseSemicolon() {
13151322
// If there's a real semicolon, then we can always parse it out.
13161323
if (token === SyntaxKind.SemicolonToken) {
@@ -2084,14 +2091,6 @@ module ts {
20842091
return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
20852092
}
20862093

2087-
2088-
2089-
function parseTokenNode<T extends Node>(): T {
2090-
var node = <T>createNode(token);
2091-
nextToken();
2092-
return finishNode(node);
2093-
}
2094-
20952094
function parseTemplateExpression(): TemplateExpression {
20962095
var template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
20972096

@@ -2801,8 +2800,9 @@ module ts {
28012800
// Expression[in] , AssignmentExpression[in]
28022801

28032802
var expr = parseAssignmentExpressionOrHigher();
2804-
while (parseOptional(SyntaxKind.CommaToken)) {
2805-
expr = makeBinaryExpression(expr, SyntaxKind.CommaToken, parseAssignmentExpressionOrHigher());
2803+
var operatorToken: Node;
2804+
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
2805+
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
28062806
}
28072807
return expr;
28082808
}
@@ -2881,9 +2881,7 @@ module ts {
28812881
// Note: we call reScanGreaterToken so that we get an appropriately merged token
28822882
// for cases like > > = becoming >>=
28832883
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
2884-
var operator = token;
2885-
nextToken();
2886-
return makeBinaryExpression(expr, operator, parseAssignmentExpressionOrHigher());
2884+
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
28872885
}
28882886

28892887
// It wasn't an assignment or a lambda. This is a conditional expression:
@@ -3187,9 +3185,7 @@ module ts {
31873185
break;
31883186
}
31893187

3190-
var operator = token;
3191-
nextToken();
3192-
leftOperand = makeBinaryExpression(leftOperand, operator, parseBinaryExpressionOrHigher(newPrecedence));
3188+
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
31933189
}
31943190

31953191
return leftOperand;
@@ -3245,10 +3241,10 @@ module ts {
32453241
return -1;
32463242
}
32473243

3248-
function makeBinaryExpression(left: Expression, operator: SyntaxKind, right: Expression): BinaryExpression {
3244+
function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
32493245
var node = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, left.pos);
32503246
node.left = left;
3251-
node.operator = operator;
3247+
node.operatorToken = operatorToken;
32523248
node.right = right;
32533249
return finishNode(node);
32543250
}

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ module ts {
623623

624624
export interface BinaryExpression extends Expression {
625625
left: Expression;
626-
operator: SyntaxKind;
626+
operatorToken: Node;
627627
right: Expression;
628628
}
629629

src/services/breakpoints.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ module ts.BreakpointResolver {
6969
return textSpan(node);
7070
}
7171

72-
if (node.parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node.parent).operator === SyntaxKind.CommaToken) {
72+
if (node.parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node.parent).operatorToken.kind === SyntaxKind.CommaToken) {
7373
// if this is comma expression, the breakpoint is possible in this expression
7474
return textSpan(node);
7575
}

src/services/formatting/formattingScanner.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,19 @@ module ts.formatting {
9393
savedPos = scanner.getStartPos();
9494
}
9595

96-
function shouldRescanGreaterThanToken(container: Node): boolean {
97-
if (container.kind !== SyntaxKind.BinaryExpression) {
98-
return false;
99-
}
100-
switch ((<BinaryExpression>container).operator) {
101-
case SyntaxKind.GreaterThanEqualsToken:
102-
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
103-
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
104-
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
105-
case SyntaxKind.GreaterThanGreaterThanToken:
106-
return true;
96+
function shouldRescanGreaterThanToken(node: Node): boolean {
97+
//if (container.kind !== SyntaxKind.BinaryExpression) {
98+
// return false;
99+
//}
100+
if (node) {
101+
switch (node.kind) {
102+
case SyntaxKind.GreaterThanEqualsToken:
103+
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
104+
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
105+
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
106+
case SyntaxKind.GreaterThanGreaterThanToken:
107+
return true;
108+
}
107109
}
108110

109111
return false;
@@ -164,7 +166,7 @@ module ts.formatting {
164166

165167
if (expectedScanAction === ScanAction.RescanGreaterThanToken && currentToken === SyntaxKind.GreaterThanToken) {
166168
currentToken = scanner.reScanGreaterToken();
167-
Debug.assert((<BinaryExpression>n).operator === currentToken);
169+
Debug.assert(n.kind === currentToken);
168170
lastScanAction = ScanAction.RescanGreaterThanToken;
169171
}
170172
else if (expectedScanAction === ScanAction.RescanSlashToken && startsWithSlashToken(currentToken)) {

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4648,7 +4648,7 @@ module ts {
46484648
return true;
46494649
}
46504650
else if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).left === node) {
4651-
var operator = (<BinaryExpression>parent).operator;
4651+
var operator = (<BinaryExpression>parent).operatorToken.kind;
46524652
return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment;
46534653
}
46544654
}

tests/baselines/reference/APISample_compile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ declare module "typescript" {
527527
}
528528
interface BinaryExpression extends Expression {
529529
left: Expression;
530-
operator: SyntaxKind;
530+
operatorToken: Node;
531531
right: Expression;
532532
}
533533
interface ConditionalExpression extends Expression {

tests/baselines/reference/APISample_compile.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,9 +1585,9 @@ declare module "typescript" {
15851585
>left : Expression
15861586
>Expression : Expression
15871587

1588-
operator: SyntaxKind;
1589-
>operator : SyntaxKind
1590-
>SyntaxKind : SyntaxKind
1588+
operatorToken: Node;
1589+
>operatorToken : Node
1590+
>Node : Node
15911591

15921592
right: Expression;
15931593
>right : Expression

0 commit comments

Comments
 (0)