Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d96a533

Browse files
[javanaut][operationExpr][1/2]feat: Add Assignment operation expr with multiply and assignment operator (#320)
* add assignment operation expr enables *= operator.
1 parent 3f098c4 commit d96a533

File tree

9 files changed

+871
-3
lines changed

9 files changed

+871
-3
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.api.generator.engine.ast;
16+
17+
import com.google.auto.value.AutoValue;
18+
import com.google.common.base.Preconditions;
19+
20+
@AutoValue
21+
public abstract class AssignmentOperationExpr implements OperationExpr {
22+
public abstract VariableExpr variableExpr();
23+
24+
public abstract Expr valueExpr();
25+
26+
public abstract OperatorKind operatorKind();
27+
28+
@Override
29+
public TypeNode type() {
30+
return variableExpr().type();
31+
}
32+
33+
@Override
34+
public void accept(AstNodeVisitor visitor) {
35+
visitor.visit(this);
36+
}
37+
38+
public static AssignmentOperationExpr xorAssignmentWithExprs(
39+
VariableExpr variableExpr, Expr valueExpr) {
40+
return builder()
41+
.setVariableExpr(variableExpr)
42+
.setValueExpr(valueExpr)
43+
.setOperatorKind(OperatorKind.ASSIGNMENT_XOR)
44+
.build();
45+
}
46+
47+
public static AssignmentOperationExpr multiplyAssignmentWithExprs(
48+
VariableExpr variableExpr, Expr valueExpr) {
49+
return builder()
50+
.setVariableExpr(variableExpr)
51+
.setValueExpr(valueExpr)
52+
.setOperatorKind(OperatorKind.ASSIGNMENT_MULTIPLY)
53+
.build();
54+
}
55+
56+
private static Builder builder() {
57+
return new AutoValue_AssignmentOperationExpr.Builder();
58+
}
59+
60+
@AutoValue.Builder
61+
abstract static class Builder {
62+
// Private setter.
63+
abstract Builder setVariableExpr(VariableExpr variableExpr);
64+
65+
// Private setter.
66+
abstract Builder setValueExpr(Expr valueExpr);
67+
68+
// Private setter.
69+
abstract Builder setOperatorKind(OperatorKind operator);
70+
71+
abstract AssignmentOperationExpr autoBuild();
72+
73+
private AssignmentOperationExpr build() {
74+
AssignmentOperationExpr assignmentOperationExpr = autoBuild();
75+
TypeNode lhsType = assignmentOperationExpr.variableExpr().variable().type();
76+
TypeNode rhsType = assignmentOperationExpr.valueExpr().type();
77+
OperatorKind operator = assignmentOperationExpr.operatorKind();
78+
79+
// Check if the variable exprs have been declared, if yes, throw error.
80+
Preconditions.checkState(
81+
!assignmentOperationExpr.variableExpr().isDecl(),
82+
String.format(
83+
"Variable `%s` should not be declaration in the variable expression.",
84+
assignmentOperationExpr.variableExpr().variable().name()));
85+
86+
// errorMsg is type checking error message for operators.
87+
final String errorMsg =
88+
String.format(
89+
"Assignment operator %s can not be applied to %s, %s.",
90+
operator, lhsType.toString(), rhsType.toString());
91+
92+
// Check type for multiply and assignment operator (*=).
93+
if (operator.equals(OperatorKind.ASSIGNMENT_MULTIPLY)) {
94+
Preconditions.checkState(isValidMultiplyAssignmentType(lhsType, rhsType), errorMsg);
95+
}
96+
97+
// Check type for XOR and assignment operator (^=).
98+
// TODO(summerji): Complete the type-checking for ^= and unit test.
99+
if (operator.equals(OperatorKind.ASSIGNMENT_XOR)) {
100+
Preconditions.checkState(isValidXORAssignmentType(lhsType, rhsType), errorMsg);
101+
}
102+
return assignmentOperationExpr;
103+
}
104+
105+
// isValidMultiplyAssignmentType validates the types for LHS variable expr and RHS expr.
106+
// *= can be only applied on Primitive numeric type.
107+
private boolean isValidMultiplyAssignmentType(TypeNode variableType, TypeNode valueType) {
108+
// LHS is numeric type, RHS should be any numeric type or any numeric boxed type.
109+
if (TypeNode.isNumericType(variableType) && !TypeNode.isBoxedType(variableType)) {
110+
return TypeNode.isNumericType(valueType);
111+
}
112+
// LHS is integer boxed type, RHS should be any numeric type except long, float, double.
113+
if (variableType.equals(TypeNode.INT)) {
114+
return TypeNode.isNumericType(valueType)
115+
&& !(valueType.equals(TypeNode.LONG) || TypeNode.isFloatingPointType(valueType));
116+
}
117+
// LHS is long boxed type, RHS should be any numeric type except float, double.
118+
if (variableType.equals(TypeNode.LONG)) {
119+
return TypeNode.isNumericType(valueType) && !TypeNode.isFloatingPointType(valueType);
120+
}
121+
// LHS is integer boxed type, RHS should be any numeric type except double.
122+
if (variableType.equals(TypeNode.FLOAT)) {
123+
return TypeNode.isNumericType(valueType) && !valueType.equals(TypeNode.DOUBLE);
124+
}
125+
// LHS is integer boxed type, RHS should be any numeric type or any numeric boxed type.
126+
if (variableType.equals(TypeNode.DOUBLE)) {
127+
return TypeNode.isNumericType(valueType);
128+
}
129+
// *= operator does not support boxed Short, Character, Byte, null, reference, void type.
130+
return false;
131+
}
132+
133+
// TODO(summerji): Complete the type-checking for ^= and unit test.
134+
private boolean isValidXORAssignmentType(TypeNode variableType, TypeNode valueType) {
135+
return true;
136+
}
137+
}
138+
}

src/main/java/com/google/api/generator/engine/ast/AstNodeVisitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public interface AstNodeVisitor {
5959

6060
public void visit(LogicalOperationExpr logicalOperationExpr);
6161

62+
public void visit(AssignmentOperationExpr assignmentOperationExpr);
63+
6264
/** =============================== COMMENT =============================== */
6365
public void visit(LineComment lineComment);
6466

src/main/java/com/google/api/generator/engine/ast/OperatorKind.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public enum OperatorKind {
2020
ARITHMETIC_ADDITION,
2121
LOGICAL_AND,
2222
LOGICAL_OR,
23+
ASSIGNMENT_XOR,
24+
ASSIGNMENT_MULTIPLY,
2325
RELATIONAL_EQUAL_TO,
2426
RELATIONAL_NOT_EQUAL_TO,
2527
RELATIONAL_LESS_THAN,

src/main/java/com/google/api/generator/engine/ast/TypeNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ public static boolean isNumericType(TypeNode type) {
174174
|| type.equals(TypeNode.BYTE);
175175
}
176176

177+
public static boolean isFloatingPointType(TypeNode type) {
178+
return type.equals(TypeNode.DOUBLE) || type.equals(TypeNode.FLOAT);
179+
}
180+
177181
public static boolean isBoxedType(TypeNode type) {
178182
return isReferenceType(type) && BOXED_TYPE_MAP.containsValue(type);
179183
}

src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.google.api.generator.engine.ast.AnonymousClassExpr;
1919
import com.google.api.generator.engine.ast.ArithmeticOperationExpr;
2020
import com.google.api.generator.engine.ast.AssignmentExpr;
21+
import com.google.api.generator.engine.ast.AssignmentOperationExpr;
2122
import com.google.api.generator.engine.ast.AstNodeVisitor;
2223
import com.google.api.generator.engine.ast.BlockComment;
2324
import com.google.api.generator.engine.ast.BlockStatement;
@@ -240,6 +241,12 @@ public void visit(LogicalOperationExpr logicalOperationExpr) {
240241
logicalOperationExpr.rhsExpr().accept(this);
241242
}
242243

244+
@Override
245+
public void visit(AssignmentOperationExpr assignmentOperationExpr) {
246+
assignmentOperationExpr.variableExpr().accept(this);
247+
assignmentOperationExpr.valueExpr().accept(this);
248+
}
249+
243250
/** =============================== STATEMENTS =============================== */
244251
@Override
245252
public void visit(ExprStatement exprStatement) {

src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.google.api.generator.engine.ast.AnonymousClassExpr;
1919
import com.google.api.generator.engine.ast.ArithmeticOperationExpr;
2020
import com.google.api.generator.engine.ast.AssignmentExpr;
21+
import com.google.api.generator.engine.ast.AssignmentOperationExpr;
2122
import com.google.api.generator.engine.ast.AstNodeVisitor;
2223
import com.google.api.generator.engine.ast.BlockComment;
2324
import com.google.api.generator.engine.ast.BlockStatement;
@@ -115,6 +116,8 @@ public class JavaWriterVisitor implements AstNodeVisitor {
115116
private static final String OPERATOR_LOGICAL_NOT = "!";
116117
private static final String OPERATOR_LOGICAL_AND = "&&";
117118
private static final String OPERATOR_LOGICAL_OR = "||";
119+
private static final String OPERATOR_XOR = "^=";
120+
private static final String OPERATOR_MULTIPLE_AND_ASSIGNMENT = "*=";
118121

119122
private final StringBuffer buffer = new StringBuffer();
120123
private final ImportWriterVisitor importWriterVisitor = new ImportWriterVisitor();
@@ -430,6 +433,15 @@ public void visit(LogicalOperationExpr logicalOperationExpr) {
430433
logicalOperationExpr.rhsExpr().accept(this);
431434
}
432435

436+
@Override
437+
public void visit(AssignmentOperationExpr assignmentOperationExpr) {
438+
assignmentOperationExpr.variableExpr().accept(this);
439+
space();
440+
operator(assignmentOperationExpr.operatorKind());
441+
space();
442+
assignmentOperationExpr.valueExpr().accept(this);
443+
}
444+
433445
/** =============================== STATEMENTS =============================== */
434446
@Override
435447
public void visit(ExprStatement exprStatement) {
@@ -913,6 +925,15 @@ private void semicolon() {
913925

914926
private void operator(OperatorKind kind) {
915927
switch (kind) {
928+
case ARITHMETIC_ADDITION:
929+
buffer.append(OPERATOR_ADDITION);
930+
break;
931+
case ASSIGNMENT_XOR:
932+
buffer.append(OPERATOR_XOR);
933+
break;
934+
case ASSIGNMENT_MULTIPLY:
935+
buffer.append(OPERATOR_MULTIPLE_AND_ASSIGNMENT);
936+
break;
916937
case RELATIONAL_EQUAL_TO:
917938
buffer.append(OPERATOR_EQUAL_TO);
918939
break;
@@ -928,9 +949,6 @@ private void operator(OperatorKind kind) {
928949
case UNARY_LOGICAL_NOT:
929950
buffer.append(OPERATOR_LOGICAL_NOT);
930951
break;
931-
case ARITHMETIC_ADDITION:
932-
buffer.append(OPERATOR_ADDITION);
933-
break;
934952
case LOGICAL_AND:
935953
buffer.append(OPERATOR_LOGICAL_AND);
936954
break;

0 commit comments

Comments
 (0)