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 ArrayAllocationExpression extends Expression { 20 21 public TypeReference type; 22 23 public Expression[] dimensions; 26 public ArrayInitializer initializer; 27 28 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { 29 for (int i = 0, max = this.dimensions.length; i < max; i++) { 30 Expression dim; 31 if ((dim = this.dimensions[i]) != null) { 32 flowInfo = dim.analyseCode(currentScope, flowContext, flowInfo); 33 } 34 } 35 if (this.initializer != null) { 36 return this.initializer.analyseCode(currentScope, flowContext, flowInfo); 37 } 38 return flowInfo; 39 } 40 41 44 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { 45 46 int pc = codeStream.position; 47 48 if (this.initializer != null) { 49 this.initializer.generateCode(currentScope, codeStream, valueRequired); 50 return; 51 } 52 53 int explicitDimCount = 0; 54 for (int i = 0, max = this.dimensions.length; i < max; i++) { 55 Expression dimExpression; 56 if ((dimExpression = this.dimensions[i]) == null) break; dimExpression.generateCode(currentScope, codeStream, true); 58 explicitDimCount++; 59 } 60 61 if (explicitDimCount == 1) { 63 codeStream.newArray((ArrayBinding)this.resolvedType); 65 } else { 66 codeStream.multianewarray(this.resolvedType, explicitDimCount); 68 } 69 if (valueRequired) { 70 codeStream.generateImplicitConversion(this.implicitConversion); 71 } else { 72 codeStream.pop(); 73 } 74 codeStream.recordPositionsFrom(pc, this.sourceStart); 75 } 76 77 78 public StringBuffer printExpression(int indent, StringBuffer output) { 79 output.append("new "); this.type.print(0, output); 81 for (int i = 0; i < this.dimensions.length; i++) { 82 if (this.dimensions[i] == null) 83 output.append("[]"); else { 85 output.append('['); 86 this.dimensions[i].printExpression(0, output); 87 output.append(']'); 88 } 89 } 90 if (this.initializer != null) this.initializer.printExpression(0, output); 91 return output; 92 } 93 94 public TypeBinding resolveType(BlockScope scope) { 95 100 TypeBinding referenceType = this.type.resolveType(scope, true ); 101 102 this.constant = Constant.NotAConstant; 104 if (referenceType == TypeBinding.VOID) { 105 scope.problemReporter().cannotAllocateVoidArray(this); 106 referenceType = null; 107 } 108 109 int explicitDimIndex = -1; 111 loop: for (int i = this.dimensions.length; --i >= 0;) { 112 if (this.dimensions[i] != null) { 113 if (explicitDimIndex < 0) explicitDimIndex = i; 114 } else if (explicitDimIndex > 0) { 115 scope.problemReporter().incorrectLocationForNonEmptyDimension(this, explicitDimIndex); 117 break loop; 118 } 119 } 120 121 if (this.initializer == null) { 124 if (explicitDimIndex < 0) { 125 scope.problemReporter().mustDefineDimensionsOrInitializer(this); 126 } 127 if (referenceType != null && !referenceType.isReifiable()) { 129 scope.problemReporter().illegalGenericArray(referenceType, this); 130 } 131 } else if (explicitDimIndex >= 0) { 132 scope.problemReporter().cannotDefineDimensionsAndInitializer(this); 133 } 134 135 for (int i = 0; i <= explicitDimIndex; i++) { 137 Expression dimExpression; 138 if ((dimExpression = this.dimensions[i]) != null) { 139 TypeBinding dimensionType = dimExpression.resolveTypeExpecting(scope, TypeBinding.INT); 140 if (dimensionType != null) { 141 this.dimensions[i].computeConversion(scope, TypeBinding.INT, dimensionType); 142 } 143 } 144 } 145 146 if (referenceType != null) { 148 if (this.dimensions.length > 255) { 149 scope.problemReporter().tooManyDimensions(this); 150 } 151 this.resolvedType = scope.createArrayType(referenceType, this.dimensions.length); 152 153 if (this.initializer != null) { 155 if ((this.initializer.resolveTypeExpecting(scope, this.resolvedType)) != null) 156 this.initializer.binding = (ArrayBinding)this.resolvedType; 157 } 158 } 159 return this.resolvedType; 160 } 161 162 163 public void traverse(ASTVisitor visitor, BlockScope scope) { 164 if (visitor.visit(this, scope)) { 165 int dimensionsLength = this.dimensions.length; 166 this.type.traverse(visitor, scope); 167 for (int i = 0; i < dimensionsLength; i++) { 168 if (this.dimensions[i] != null) 169 this.dimensions[i].traverse(visitor, scope); 170 } 171 if (this.initializer != null) 172 this.initializer.traverse(visitor, scope); 173 } 174 visitor.endVisit(this, scope); 175 } 176 } 177 | Popular Tags |