X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/CompoundAssignment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/CompoundAssignment.java index 4dd83aa..5f6649e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/CompoundAssignment.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/CompoundAssignment.java @@ -1,141 +1,174 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. + * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html + * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.ast; -import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; -import net.sourceforge.phpdt.internal.compiler.codegen.*; -import net.sourceforge.phpdt.internal.compiler.flow.*; -import net.sourceforge.phpdt.internal.compiler.lookup.*; +import net.sourceforge.phpdt.internal.compiler.ASTVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; 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 - - super(lhs, expression, sourceEnd); - 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. + 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 - return lhs.analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits(); -} -public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + super(lhs, expression, sourceEnd); + lhs.bits &= ~IsStrictlyAssignedMASK; // tag lhs as NON assigned - it + // is also a read access + this.operator = operator; + } - // 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. + 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. - int pc = codeStream.position; - lhs.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired); - if (valueRequired) { - codeStream.generateImplicitConversion(implicitConversion); + return ((Reference) lhs).analyseAssignment(currentScope, flowContext, + flowInfo, this, true).unconditionalInits(); } - codeStream.recordPositionsFrom(pc, this.sourceStart); -} -public String operatorToString() { - switch (operator) { - case PLUS : + + // 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; - 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)) { - // += 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()){ - // += 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)) { + // += is illegal + scope.problemReporter().invalidOperator(this, lhsType, + expressionType); + return null; + } else if ((lhsType.isNumericType() || lhsId == T_boolean) + && !expressionType.isNumericType()) { + // += 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 lhsType; -} -public boolean restrainUsageToNumericTypes(){ - return false ;} -public String toStringExpressionNoParenthesis() { - - return lhs.toStringExpression() + " " + //$NON-NLS-1$ - operatorToString() + " " + //$NON-NLS-1$ - expression.toStringExpression() ; } -public void traverse(IAbstractSyntaxTreeVisitor 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); -} }