1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.ASTVisitor; 14 import org.eclipse.jdt.internal.compiler.impl.*; 15 import org.eclipse.jdt.internal.compiler.codegen.*; 16 import org.eclipse.jdt.internal.compiler.flow.*; 17 import org.eclipse.jdt.internal.compiler.lookup.*; 18 19 public class ArrayReference extends Reference { 20 21 public Expression receiver; 22 public Expression position; 23 24 public ArrayReference(Expression rec, Expression pos) { 25 this.receiver = rec; 26 this.position = pos; 27 sourceStart = rec.sourceStart; 28 } 29 30 public FlowInfo analyseAssignment( 31 BlockScope currentScope, 32 FlowContext flowContext, 33 FlowInfo flowInfo, 34 Assignment assignment, 35 boolean compoundAssignment) { 36 if (assignment.expression == null) { 38 return analyseCode(currentScope, flowContext, flowInfo); 39 } 40 return assignment 41 .expression 42 .analyseCode( 43 currentScope, 44 flowContext, 45 analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()); 46 } 47 48 public FlowInfo analyseCode( 49 BlockScope currentScope, 50 FlowContext flowContext, 51 FlowInfo flowInfo) { 52 receiver.checkNPE(currentScope, flowContext, flowInfo); 53 flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo); 54 return position.analyseCode(currentScope, flowContext, flowInfo); 55 } 56 57 public void generateAssignment( 58 BlockScope currentScope, 59 CodeStream codeStream, 60 Assignment assignment, 61 boolean valueRequired) { 62 63 int pc = codeStream.position; 64 receiver.generateCode(currentScope, codeStream, true); 65 if (receiver instanceof CastExpression && ((CastExpression)receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ 67 codeStream.checkcast(receiver.resolvedType); 68 } 69 codeStream.recordPositionsFrom(pc, this.sourceStart); 70 position.generateCode(currentScope, codeStream, true); 71 assignment.expression.generateCode(currentScope, codeStream, true); 72 codeStream.arrayAtPut(this.resolvedType.id, valueRequired); 73 if (valueRequired) { 74 codeStream.generateImplicitConversion(assignment.implicitConversion); 75 } 76 } 77 78 81 public void generateCode( 82 BlockScope currentScope, 83 CodeStream codeStream, 84 boolean valueRequired) { 85 86 int pc = codeStream.position; 87 receiver.generateCode(currentScope, codeStream, true); 88 if (receiver instanceof CastExpression && ((CastExpression)receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ 90 codeStream.checkcast(receiver.resolvedType); 91 } 92 position.generateCode(currentScope, codeStream, true); 93 codeStream.arrayAt(this.resolvedType.id); 94 if (valueRequired) { 96 codeStream.generateImplicitConversion(implicitConversion); 97 } else { 98 boolean isUnboxing = (implicitConversion & TypeIds.UNBOXING) != 0; 99 if (isUnboxing) codeStream.generateImplicitConversion(implicitConversion); 101 switch (isUnboxing ? postConversionType(currentScope).id : this.resolvedType.id) { 102 case T_long : 103 case T_double : 104 codeStream.pop2(); 105 break; 106 default : 107 codeStream.pop(); 108 } 109 } 110 codeStream.recordPositionsFrom(pc, this.sourceStart); 111 } 112 113 public void generateCompoundAssignment( 114 BlockScope currentScope, 115 CodeStream codeStream, 116 Expression expression, 117 int operator, 118 int assignmentImplicitConversion, 119 boolean valueRequired) { 120 121 receiver.generateCode(currentScope, codeStream, true); 122 if (receiver instanceof CastExpression && ((CastExpression)receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ 124 codeStream.checkcast(receiver.resolvedType); 125 } 126 position.generateCode(currentScope, codeStream, true); 127 codeStream.dup2(); 128 codeStream.arrayAt(this.resolvedType.id); 129 int operationTypeID; 130 switch(operationTypeID = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { 131 case T_JavaLangString : 132 case T_JavaLangObject : 133 case T_undefined : 134 codeStream.generateStringConcatenationAppend(currentScope, null, expression); 135 break; 136 default : 137 codeStream.generateImplicitConversion(implicitConversion); 139 if (expression == IntLiteral.One) { codeStream.generateConstant(expression.constant, implicitConversion); 142 } else { 143 expression.generateCode(currentScope, codeStream, true); 144 } 145 codeStream.sendOperator(operator, operationTypeID); 147 codeStream.generateImplicitConversion(assignmentImplicitConversion); 149 } 150 codeStream.arrayAtPut(this.resolvedType.id, valueRequired); 151 } 152 153 public void generatePostIncrement( 154 BlockScope currentScope, 155 CodeStream codeStream, 156 CompoundAssignment postIncrement, 157 boolean valueRequired) { 158 159 receiver.generateCode(currentScope, codeStream, true); 160 if (receiver instanceof CastExpression && ((CastExpression)receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ 162 codeStream.checkcast(receiver.resolvedType); 163 } 164 position.generateCode(currentScope, codeStream, true); 165 codeStream.dup2(); 166 codeStream.arrayAt(this.resolvedType.id); 167 if (valueRequired) { 168 if ((this.resolvedType == TypeBinding.LONG) 169 || (this.resolvedType == TypeBinding.DOUBLE)) { 170 codeStream.dup2_x2(); 171 } else { 172 codeStream.dup_x2(); 173 } 174 } 175 codeStream.generateImplicitConversion(implicitConversion); 176 codeStream.generateConstant( 177 postIncrement.expression.constant, 178 implicitConversion); 179 codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK); 180 codeStream.generateImplicitConversion( 181 postIncrement.preAssignImplicitConversion); 182 codeStream.arrayAtPut(this.resolvedType.id, false); 183 } 184 185 public int nullStatus(FlowInfo flowInfo) { 186 return FlowInfo.UNKNOWN; 187 } 188 189 public StringBuffer printExpression(int indent, StringBuffer output) { 190 191 receiver.printExpression(0, output).append('['); 192 return position.printExpression(0, output).append(']'); 193 } 194 195 public TypeBinding resolveType(BlockScope scope) { 196 197 constant = Constant.NotAConstant; 198 if (receiver instanceof CastExpression && ((CastExpression)receiver).innermostCastedExpression() instanceof NullLiteral) { 200 this.receiver.bits |= DisableUnnecessaryCastCheck; } 202 TypeBinding arrayType = receiver.resolveType(scope); 203 if (arrayType != null) { 204 receiver.computeConversion(scope, arrayType, arrayType); 205 if (arrayType.isArrayType()) { 206 TypeBinding elementType = ((ArrayBinding) arrayType).elementsType(); 207 this.resolvedType = ((this.bits & IsStrictlyAssigned) == 0) ? elementType.capture(scope, this.sourceEnd) : elementType; 208 } else { 209 scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this); 210 } 211 } 212 TypeBinding positionType = position.resolveTypeExpecting(scope, TypeBinding.INT); 213 if (positionType != null) { 214 position.computeConversion(scope, TypeBinding.INT, positionType); 215 } 216 return this.resolvedType; 217 } 218 219 public void traverse(ASTVisitor visitor, BlockScope scope) { 220 221 if (visitor.visit(this, scope)) { 222 receiver.traverse(visitor, scope); 223 position.traverse(visitor, scope); 224 } 225 visitor.endVisit(this, scope); 226 } 227 } 228 | Popular Tags |