public class CompoundAssignment extends Assignment implements OperatorIds {
public int operator;
+
public int assignmentImplicitConversion;
- // var op exp is equivalent to var = (varType) var op exp
+ // var op exp is equivalent to var = (varType) var op exp
// assignmentImplicitConversion stores the cast needed for the assignment
-public CompoundAssignment(Expression lhs, Expression expression,int operator, int sourceEnd) {
- //lhs is always a reference by construction ,
- //but is build as an expression ==> the checkcast cannot fail
+ public CompoundAssignment(Expression lhs, Expression expression,
+ int operator, int sourceEnd) {
+ // lhs is always a reference by construction ,
+ // but is build as an expression ==> the checkcast cannot fail
- super(lhs, expression, sourceEnd);
- lhs.bits &= ~IsStrictlyAssignedMASK; // tag lhs as NON assigned - it is also a read access
- this.operator = operator ;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
- // record setting a variable: various scenarii are possible, setting an array reference,
- // a field reference, a blank final field reference, a field of an enclosing instance or
- // just a local variable.
+ super(lhs, expression, sourceEnd);
+ lhs.bits &= ~IsStrictlyAssignedMASK; // tag lhs as NON assigned - it
+ // is also a read access
+ this.operator = operator;
+ }
- return ((Reference) lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
-}
-//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-//
-// // various scenarii are possible, setting an array reference,
-// // a field reference, a blank final field reference, a field of an enclosing instance or
-// // just a local variable.
-//
-// int pc = codeStream.position;
-// ((Reference) lhs).generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
-// if (valueRequired) {
-// codeStream.generateImplicitConversion(implicitConversion);
-// }
-// codeStream.recordPositionsFrom(pc, this.sourceStart);
-//}
-public String operatorToString() {
- switch (operator) {
- case PLUS :
+ public FlowInfo analyseCode(BlockScope currentScope,
+ FlowContext flowContext, FlowInfo flowInfo) {
+ // record setting a variable: various scenarii are possible, setting an
+ // array reference,
+ // a field reference, a blank final field reference, a field of an
+ // enclosing instance or
+ // just a local variable.
+
+ return ((Reference) lhs).analyseAssignment(currentScope, flowContext,
+ flowInfo, this, true).unconditionalInits();
+ }
+
+ // public void generateCode(BlockScope currentScope, CodeStream codeStream,
+ // boolean valueRequired) {
+ //
+ // // various scenarii are possible, setting an array reference,
+ // // a field reference, a blank final field reference, a field of an
+ // enclosing instance or
+ // // just a local variable.
+ //
+ // int pc = codeStream.position;
+ // ((Reference) lhs).generateCompoundAssignment(currentScope, codeStream,
+ // expression, operator, assignmentImplicitConversion, valueRequired);
+ // if (valueRequired) {
+ // codeStream.generateImplicitConversion(implicitConversion);
+ // }
+ // codeStream.recordPositionsFrom(pc, this.sourceStart);
+ // }
+ public String operatorToString() {
+ switch (operator) {
+ case PLUS:
return "+="; //$NON-NLS-1$
- case MINUS :
+ case MINUS:
return "-="; //$NON-NLS-1$
- case MULTIPLY :
+ case MULTIPLY:
return "*="; //$NON-NLS-1$
- case DIVIDE :
+ case DIVIDE:
return "/="; //$NON-NLS-1$
- case AND :
+ case AND:
return "&="; //$NON-NLS-1$
- case OR :
+ case OR:
return "|="; //$NON-NLS-1$
- case XOR :
+ case XOR:
return "^="; //$NON-NLS-1$
- case REMAINDER :
+ case REMAINDER:
return "%="; //$NON-NLS-1$
- case LEFT_SHIFT :
+ case LEFT_SHIFT:
return "<<="; //$NON-NLS-1$
- case RIGHT_SHIFT :
+ case RIGHT_SHIFT:
return ">>="; //$NON-NLS-1$
- case UNSIGNED_RIGHT_SHIFT :
+ case UNSIGNED_RIGHT_SHIFT:
return ">>>="; //$NON-NLS-1$
- };
- return "unknown operator"; //$NON-NLS-1$
-}
-public TypeBinding resolveType(BlockScope scope) {
- constant = NotAConstant;
- if (!(this.lhs instanceof Reference)) {
- scope.problemReporter().expressionShouldBeAVariable(this.lhs);
- }
- TypeBinding lhsType = lhs.resolveType(scope);
- TypeBinding expressionType = expression.resolveType(scope);
- if (lhsType == null || expressionType == null)
- return null;
-
- int lhsId = lhsType.id;
- int expressionId = expressionType.id;
- if (restrainUsageToNumericTypes() && !lhsType.isNumericType()) {
- scope.problemReporter().operatorOnlyValidOnNumericType(this, lhsType, expressionType);
- return null;
- }
- if (lhsId > 15 || expressionId > 15) {
- if (lhsId != T_String) { // String += Object is valid wheraas Object -= String is not
- scope.problemReporter().invalidOperator(this, lhsType, expressionType);
- return null;
}
- expressionId = T_Object; // use the Object has tag table
+ ;
+ return "unknown operator"; //$NON-NLS-1$
}
- // the code is an int
- // (cast) left Op (cast) rigth --> result
- // 0000 0000 0000 0000 0000
- // <<16 <<12 <<8 <<4 <<0
+ public TypeBinding resolveType(BlockScope scope) {
+ constant = NotAConstant;
+ if (!(this.lhs instanceof Reference)) {
+ scope.problemReporter().expressionShouldBeAVariable(this.lhs);
+ }
+ TypeBinding lhsType = lhs.resolveType(scope);
+ TypeBinding expressionType = expression.resolveType(scope);
+ if (lhsType == null || expressionType == null)
+ return null;
- // the conversion is stored INTO the reference (info needed for the code gen)
- int result = OperatorExpression.ResolveTypeTables[operator][ (lhsId << 4) + expressionId];
- if (result == T_undefined) {
- scope.problemReporter().invalidOperator(this, lhsType, expressionType);
- return null;
- }
- if (operator == PLUS){
- if(scope.isJavaLangObject(lhsType)) {
- // <Object> += <String> is illegal
- scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+ int lhsId = lhsType.id;
+ int expressionId = expressionType.id;
+ if (restrainUsageToNumericTypes() && !lhsType.isNumericType()) {
+ scope.problemReporter().operatorOnlyValidOnNumericType(this,
+ lhsType, expressionType);
return null;
- } else if ((lhsType.isNumericType() || lhsId == T_boolean) && !expressionType.isNumericType()){
- // <int | boolean> += <String> is illegal
- scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+ }
+ if (lhsId > 15 || expressionId > 15) {
+ if (lhsId != T_String) { // String += Object is valid wheraas
+ // Object -= String is not
+ scope.problemReporter().invalidOperator(this, lhsType,
+ expressionType);
+ return null;
+ }
+ expressionId = T_Object; // use the Object has tag table
+ }
+
+ // the code is an int
+ // (cast) left Op (cast) rigth --> result
+ // 0000 0000 0000 0000 0000
+ // <<16 <<12 <<8 <<4 <<0
+
+ // the conversion is stored INTO the reference (info needed for the code
+ // gen)
+ int result = OperatorExpression.ResolveTypeTables[operator][(lhsId << 4)
+ + expressionId];
+ if (result == T_undefined) {
+ scope.problemReporter().invalidOperator(this, lhsType,
+ expressionType);
return null;
}
+ if (operator == PLUS) {
+ if (scope.isJavaLangObject(lhsType)) {
+ // <Object> += <String> is illegal
+ scope.problemReporter().invalidOperator(this, lhsType,
+ expressionType);
+ return null;
+ } else if ((lhsType.isNumericType() || lhsId == T_boolean)
+ && !expressionType.isNumericType()) {
+ // <int | boolean> += <String> is illegal
+ scope.problemReporter().invalidOperator(this, lhsType,
+ expressionType);
+ return null;
+ }
+ }
+ lhs.implicitConversion = result >>> 12;
+ expression.implicitConversion = (result >>> 4) & 0x000FF;
+ assignmentImplicitConversion = (lhsId << 4) + (result & 0x0000F);
+ return this.resolvedType = lhsType;
}
- lhs.implicitConversion = result >>> 12;
- expression.implicitConversion = (result >>> 4) & 0x000FF;
- assignmentImplicitConversion = (lhsId << 4) + (result & 0x0000F);
- return this.resolvedType = lhsType;
-}
-public boolean restrainUsageToNumericTypes(){
- return false ;}
-public String toStringExpressionNoParenthesis() {
-
- return lhs.toStringExpression() + " " + //$NON-NLS-1$
- operatorToString() + " " + //$NON-NLS-1$
- expression.toStringExpression() ; }
-public void traverse(ASTVisitor visitor, BlockScope scope) {
- if (visitor.visit(this, scope)) {
- lhs.traverse(visitor, scope);
- expression.traverse(visitor, scope);
+
+ public boolean restrainUsageToNumericTypes() {
+ return false;
+ }
+
+ public String toStringExpressionNoParenthesis() {
+
+ return lhs.toStringExpression() + " " + //$NON-NLS-1$
+ operatorToString() + " " + //$NON-NLS-1$
+ expression.toStringExpression();
+ }
+
+ public void traverse(ASTVisitor visitor, BlockScope scope) {
+ if (visitor.visit(this, scope)) {
+ lhs.traverse(visitor, scope);
+ expression.traverse(visitor, scope);
+ }
+ visitor.endVisit(this, scope);
}
- visitor.endVisit(this, scope);
-}
}