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.codegen.CodeStream; 15 import org.eclipse.jdt.internal.compiler.flow.FlowContext; 16 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 17 import org.eclipse.jdt.internal.compiler.impl.Constant; 18 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 19 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 20 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 21 22 48 public class CombinedBinaryExpression extends BinaryExpression { 49 50 59 public int arity; 60 61 67 public int arityMax; 68 69 72 public static final int ARITY_MAX_MAX = 160; 73 74 77 public static final int ARITY_MAX_MIN = 20; 78 79 84 public static int defaultArityMaxStartingValue = ARITY_MAX_MIN; 85 86 93 public BinaryExpression referencesTable[]; 94 95 109 public CombinedBinaryExpression(Expression left, Expression right, int operator, 110 int arity) { 111 super(left, right, operator); 112 this.arity = arity; 113 if (arity > 1) { 114 this.referencesTable = new BinaryExpression[arity]; 115 this.referencesTable[arity - 1] = (BinaryExpression) left; 116 for (int i = arity - 1; i > 0; i--) { 117 this.referencesTable[i - 1] = 118 (BinaryExpression) this.referencesTable[i].left; 119 } 120 } else { 121 this.arityMax = defaultArityMaxStartingValue; 122 } 123 } 124 125 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, 126 FlowInfo flowInfo) { 127 if (this.referencesTable == null) { 129 return super.analyseCode(currentScope, flowContext, flowInfo); 130 } 131 BinaryExpression cursor; 132 if ((cursor = this.referencesTable[0]).resolvedType.id != 133 TypeIds.T_JavaLangString) { 134 cursor.left.checkNPE(currentScope, flowContext, flowInfo); 135 } 136 flowInfo = cursor.left.analyseCode(currentScope, flowContext, flowInfo). 137 unconditionalInits(); 138 for (int i = 0, end = this.arity; i < end; i ++) { 139 if ((cursor = this.referencesTable[i]).resolvedType.id != 140 TypeIds.T_JavaLangString) { 141 cursor.right.checkNPE(currentScope, flowContext, flowInfo); 142 } 143 flowInfo = cursor.right. 144 analyseCode(currentScope, flowContext, flowInfo). 145 unconditionalInits(); 146 } 147 if (this.resolvedType.id != TypeIds.T_JavaLangString) { 148 this.right.checkNPE(currentScope, flowContext, flowInfo); 149 } 150 return this.right.analyseCode(currentScope, flowContext, flowInfo). 151 unconditionalInits(); 152 } 153 154 public void generateOptimizedStringConcatenation(BlockScope blockScope, 155 CodeStream codeStream, int typeID) { 156 if (this.referencesTable == null) { 159 super.generateOptimizedStringConcatenation(blockScope, codeStream, 160 typeID); 161 } else { 162 if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == 163 OperatorIds.PLUS) 164 && ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) { 165 if (this.constant != Constant.NotAConstant) { 166 codeStream.generateConstant(this.constant, this.implicitConversion); 167 codeStream.invokeStringConcatenationAppendForType( 168 this.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 169 } else { 170 BinaryExpression cursor = this.referencesTable[0]; 171 172 int restart = 0; 173 int pc = codeStream.position; 175 for (restart = this.arity - 1; restart >= 0; restart--) { 176 if ((cursor = this.referencesTable[restart]).constant != 177 Constant.NotAConstant) { 178 codeStream.generateConstant(cursor.constant, 179 cursor.implicitConversion); 180 codeStream.invokeStringConcatenationAppendForType( 181 cursor.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 182 break; 183 } 184 } 202 restart++; 203 if (restart == 0) { cursor.left.generateOptimizedStringConcatenation( 205 blockScope, 206 codeStream, 207 cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 208 } 209 int pcAux; 210 for (int i = restart; i < this.arity; i++) { 211 codeStream.recordPositionsFrom(pc, 212 (cursor = this.referencesTable[i]).left.sourceStart); 213 pcAux = codeStream.position; 214 cursor.right.generateOptimizedStringConcatenation(blockScope, 215 codeStream, cursor.right.implicitConversion & 216 TypeIds.COMPILE_TYPE_MASK); 217 codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart); 218 } 219 codeStream.recordPositionsFrom(pc, this.left.sourceStart); 220 pc = codeStream.position; 221 this.right.generateOptimizedStringConcatenation( 222 blockScope, 223 codeStream, 224 this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 225 codeStream.recordPositionsFrom(pc, this.right.sourceStart); 226 } 227 } else { 228 super.generateOptimizedStringConcatenation(blockScope, codeStream, 229 typeID); 230 } 231 } 232 } 233 234 public void generateOptimizedStringConcatenationCreation(BlockScope blockScope, 235 CodeStream codeStream, int typeID) { 236 if (this.referencesTable == null) { 239 super.generateOptimizedStringConcatenationCreation(blockScope, 240 codeStream, typeID); 241 } else { 242 if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == 243 OperatorIds.PLUS) && 244 ((this.bits & ASTNode.ReturnTypeIDMASK) == 245 TypeIds.T_JavaLangString) && 246 this.constant == Constant.NotAConstant) { 247 int pc = codeStream.position; 248 BinaryExpression cursor = this.referencesTable[this.arity - 1]; 249 int restart = 0; 251 for (restart = this.arity - 1; restart >= 0; restart--) { 252 if (((((cursor = this.referencesTable[restart]).bits & 253 ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == 254 OperatorIds.PLUS) && 255 ((cursor.bits & ASTNode.ReturnTypeIDMASK) == 256 TypeIds.T_JavaLangString)) { 257 if (cursor.constant != Constant.NotAConstant) { 258 codeStream.newStringContatenation(); codeStream.dup(); 260 codeStream.ldc(cursor.constant.stringValue()); 261 codeStream.invokeStringConcatenationStringConstructor(); 262 break; 264 } 265 } else { 266 cursor.generateOptimizedStringConcatenationCreation(blockScope, 267 codeStream, cursor.implicitConversion & 268 TypeIds.COMPILE_TYPE_MASK); 269 break; 270 } 271 } 272 restart++; 273 if (restart == 0) { cursor.left.generateOptimizedStringConcatenationCreation( 275 blockScope, 276 codeStream, 277 cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 278 } 279 int pcAux; 280 for (int i = restart; i < this.arity; i++) { 281 codeStream.recordPositionsFrom(pc, 282 (cursor = this.referencesTable[i]).left.sourceStart); 283 pcAux = codeStream.position; 284 cursor.right.generateOptimizedStringConcatenation(blockScope, 285 codeStream, cursor.right.implicitConversion & 286 TypeIds.COMPILE_TYPE_MASK); 287 codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart); 288 } 289 codeStream.recordPositionsFrom(pc, this.left.sourceStart); 290 pc = codeStream.position; 291 this.right.generateOptimizedStringConcatenation( 292 blockScope, 293 codeStream, 294 this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK); 295 codeStream.recordPositionsFrom(pc, this.right.sourceStart); 296 } else { 297 super.generateOptimizedStringConcatenationCreation(blockScope, 298 codeStream, typeID); 299 } 300 } 301 } 302 303 public StringBuffer printExpressionNoParenthesis(int indent, 304 StringBuffer output) { 305 if (this.referencesTable == null) { 309 return super.printExpressionNoParenthesis(indent, output); 310 } 311 String operatorString = operatorToString(); 312 for (int i = this.arity - 1; i >= 0; i--) { 313 output.append('('); 314 } 315 output = this.referencesTable[0].left. 316 printExpression(indent, output); 317 for (int i = 0, end = this.arity; 318 i < end; i++) { 319 output.append(' ').append(operatorString).append(' '); 320 output = this.referencesTable[i].right. 321 printExpression(0, output); 322 output.append(')'); 323 } 324 output.append(' ').append(operatorString).append(' '); 325 return this.right.printExpression(0, output); 326 } 327 328 public TypeBinding resolveType(BlockScope scope) { 329 if (this.referencesTable == null) { 331 return super.resolveType(scope); 332 } 333 BinaryExpression cursor; 334 if ((cursor = this.referencesTable[0]).left instanceof CastExpression) { 335 cursor.left.bits |= ASTNode.DisableUnnecessaryCastCheck; 336 } 338 cursor.left.resolveType(scope); 339 for (int i = 0, end = this.arity; i < end; i ++) { 340 this.referencesTable[i].nonRecursiveResolveTypeUpwards(scope); 341 } 342 nonRecursiveResolveTypeUpwards(scope); 343 return this.resolvedType; 344 } 345 346 public void traverse(ASTVisitor visitor, BlockScope scope) { 347 if (this.referencesTable == null) { 348 super.traverse(visitor, scope); 349 } else { 350 if (visitor.visit(this, scope)) { 351 int restart; 352 for (restart = this.arity - 1; 353 restart >= 0; 354 restart--) { 355 if (!visitor.visit( 356 this.referencesTable[restart], scope)) { 357 visitor.endVisit( 358 this.referencesTable[restart], scope); 359 break; 360 } 361 } 362 restart++; 363 if (restart == 0) { 366 this.referencesTable[0].left.traverse(visitor, scope); 367 } 368 for (int i = restart, end = this.arity; 369 i < end; i++) { 370 this.referencesTable[i].right.traverse(visitor, scope); 371 visitor.endVisit(this.referencesTable[i], scope); 372 } 373 this.right.traverse(visitor, scope); 374 } 375 visitor.endVisit(this, scope); 376 } 377 } 378 379 386 public void tuneArityMax() { 389 if (this.arityMax < ARITY_MAX_MAX) { 390 this.arityMax *= 2; 391 } 392 } 393 } 394 | Popular Tags |