1 11 package org.eclipse.jdt.internal.debug.eval.ast.engine; 12 13 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Stack ; 18 19 import org.eclipse.jdt.core.Flags; 20 import org.eclipse.jdt.core.Signature; 21 import org.eclipse.jdt.core.compiler.IProblem; 22 import org.eclipse.jdt.core.dom.ASTNode; 23 import org.eclipse.jdt.core.dom.ASTVisitor; 24 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 25 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; 26 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 27 import org.eclipse.jdt.core.dom.ArrayAccess; 28 import org.eclipse.jdt.core.dom.ArrayCreation; 29 import org.eclipse.jdt.core.dom.ArrayInitializer; 30 import org.eclipse.jdt.core.dom.ArrayType; 31 import org.eclipse.jdt.core.dom.AssertStatement; 32 import org.eclipse.jdt.core.dom.Assignment; 33 import org.eclipse.jdt.core.dom.Block; 34 import org.eclipse.jdt.core.dom.BlockComment; 35 import org.eclipse.jdt.core.dom.BooleanLiteral; 36 import org.eclipse.jdt.core.dom.BreakStatement; 37 import org.eclipse.jdt.core.dom.CastExpression; 38 import org.eclipse.jdt.core.dom.CatchClause; 39 import org.eclipse.jdt.core.dom.CharacterLiteral; 40 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 41 import org.eclipse.jdt.core.dom.CompilationUnit; 42 import org.eclipse.jdt.core.dom.ConditionalExpression; 43 import org.eclipse.jdt.core.dom.ConstructorInvocation; 44 import org.eclipse.jdt.core.dom.ContinueStatement; 45 import org.eclipse.jdt.core.dom.DoStatement; 46 import org.eclipse.jdt.core.dom.EmptyStatement; 47 import org.eclipse.jdt.core.dom.EnhancedForStatement; 48 import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 49 import org.eclipse.jdt.core.dom.EnumDeclaration; 50 import org.eclipse.jdt.core.dom.Expression; 51 import org.eclipse.jdt.core.dom.ExpressionStatement; 52 import org.eclipse.jdt.core.dom.FieldAccess; 53 import org.eclipse.jdt.core.dom.FieldDeclaration; 54 import org.eclipse.jdt.core.dom.ForStatement; 55 import org.eclipse.jdt.core.dom.IBinding; 56 import org.eclipse.jdt.core.dom.IMethodBinding; 57 import org.eclipse.jdt.core.dom.IPackageBinding; 58 import org.eclipse.jdt.core.dom.ITypeBinding; 59 import org.eclipse.jdt.core.dom.IVariableBinding; 60 import org.eclipse.jdt.core.dom.IfStatement; 61 import org.eclipse.jdt.core.dom.ImportDeclaration; 62 import org.eclipse.jdt.core.dom.InfixExpression; 63 import org.eclipse.jdt.core.dom.Initializer; 64 import org.eclipse.jdt.core.dom.InstanceofExpression; 65 import org.eclipse.jdt.core.dom.Javadoc; 66 import org.eclipse.jdt.core.dom.LabeledStatement; 67 import org.eclipse.jdt.core.dom.LineComment; 68 import org.eclipse.jdt.core.dom.MarkerAnnotation; 69 import org.eclipse.jdt.core.dom.MemberRef; 70 import org.eclipse.jdt.core.dom.MemberValuePair; 71 import org.eclipse.jdt.core.dom.MethodDeclaration; 72 import org.eclipse.jdt.core.dom.MethodInvocation; 73 import org.eclipse.jdt.core.dom.MethodRef; 74 import org.eclipse.jdt.core.dom.MethodRefParameter; 75 import org.eclipse.jdt.core.dom.Modifier; 76 import org.eclipse.jdt.core.dom.Name; 77 import org.eclipse.jdt.core.dom.NormalAnnotation; 78 import org.eclipse.jdt.core.dom.NullLiteral; 79 import org.eclipse.jdt.core.dom.NumberLiteral; 80 import org.eclipse.jdt.core.dom.PackageDeclaration; 81 import org.eclipse.jdt.core.dom.ParameterizedType; 82 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 83 import org.eclipse.jdt.core.dom.PostfixExpression; 84 import org.eclipse.jdt.core.dom.PrefixExpression; 85 import org.eclipse.jdt.core.dom.PrimitiveType; 86 import org.eclipse.jdt.core.dom.QualifiedName; 87 import org.eclipse.jdt.core.dom.QualifiedType; 88 import org.eclipse.jdt.core.dom.ReturnStatement; 89 import org.eclipse.jdt.core.dom.SimpleName; 90 import org.eclipse.jdt.core.dom.SimpleType; 91 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 92 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 93 import org.eclipse.jdt.core.dom.Statement; 94 import org.eclipse.jdt.core.dom.StringLiteral; 95 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 96 import org.eclipse.jdt.core.dom.SuperFieldAccess; 97 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 98 import org.eclipse.jdt.core.dom.SwitchCase; 99 import org.eclipse.jdt.core.dom.SwitchStatement; 100 import org.eclipse.jdt.core.dom.SynchronizedStatement; 101 import org.eclipse.jdt.core.dom.TagElement; 102 import org.eclipse.jdt.core.dom.TextElement; 103 import org.eclipse.jdt.core.dom.ThisExpression; 104 import org.eclipse.jdt.core.dom.ThrowStatement; 105 import org.eclipse.jdt.core.dom.TryStatement; 106 import org.eclipse.jdt.core.dom.Type; 107 import org.eclipse.jdt.core.dom.TypeDeclaration; 108 import org.eclipse.jdt.core.dom.TypeDeclarationStatement; 109 import org.eclipse.jdt.core.dom.TypeLiteral; 110 import org.eclipse.jdt.core.dom.TypeParameter; 111 import org.eclipse.jdt.core.dom.VariableDeclarationExpression; 112 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 113 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 114 import org.eclipse.jdt.core.dom.WhileStatement; 115 import org.eclipse.jdt.core.dom.WildcardType; 116 import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndAssignmentOperator; 117 import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndOperator; 118 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAllocation; 119 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayInitializerInstruction; 120 import org.eclipse.jdt.internal.debug.eval.ast.instructions.AssignmentOperator; 121 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Cast; 122 import org.eclipse.jdt.internal.debug.eval.ast.instructions.CompoundInstruction; 123 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ConditionalJump; 124 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Constructor; 125 import org.eclipse.jdt.internal.debug.eval.ast.instructions.DivideAssignmentOperator; 126 import org.eclipse.jdt.internal.debug.eval.ast.instructions.DivideOperator; 127 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Dup; 128 import org.eclipse.jdt.internal.debug.eval.ast.instructions.DupX1; 129 import org.eclipse.jdt.internal.debug.eval.ast.instructions.EqualEqualOperator; 130 import org.eclipse.jdt.internal.debug.eval.ast.instructions.GreaterEqualOperator; 131 import org.eclipse.jdt.internal.debug.eval.ast.instructions.GreaterOperator; 132 import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstanceOfOperator; 133 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Instruction; 134 import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstructionSequence; 135 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Jump; 136 import org.eclipse.jdt.internal.debug.eval.ast.instructions.LeftShiftAssignmentOperator; 137 import org.eclipse.jdt.internal.debug.eval.ast.instructions.LeftShiftOperator; 138 import org.eclipse.jdt.internal.debug.eval.ast.instructions.LessEqualOperator; 139 import org.eclipse.jdt.internal.debug.eval.ast.instructions.LessOperator; 140 import org.eclipse.jdt.internal.debug.eval.ast.instructions.LocalVariableCreation; 141 import org.eclipse.jdt.internal.debug.eval.ast.instructions.MinusAssignmentOperator; 142 import org.eclipse.jdt.internal.debug.eval.ast.instructions.MinusOperator; 143 import org.eclipse.jdt.internal.debug.eval.ast.instructions.MultiplyAssignmentOperator; 144 import org.eclipse.jdt.internal.debug.eval.ast.instructions.MultiplyOperator; 145 import org.eclipse.jdt.internal.debug.eval.ast.instructions.NoOp; 146 import org.eclipse.jdt.internal.debug.eval.ast.instructions.NotOperator; 147 import org.eclipse.jdt.internal.debug.eval.ast.instructions.OrAssignmentOperator; 148 import org.eclipse.jdt.internal.debug.eval.ast.instructions.OrOperator; 149 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PlusAssignmentOperator; 150 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PlusOperator; 151 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Pop; 152 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PostfixMinusMinusOperator; 153 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PostfixPlusPlusOperator; 154 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PrefixMinusMinusOperator; 155 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PrefixPlusPlusOperator; 156 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushArrayLength; 157 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushArrayType; 158 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushBoolean; 159 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushChar; 160 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushClassLiteralValue; 161 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushDouble; 162 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushFieldVariable; 163 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushFloat; 164 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushInt; 165 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushLocalVariable; 166 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushLong; 167 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushNull; 168 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushStaticFieldVariable; 169 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushString; 170 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushThis; 171 import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushType; 172 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderAssignmentOperator; 173 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderOperator; 174 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ReturnInstruction; 175 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftAssignmentOperator; 176 import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftOperator; 177 import org.eclipse.jdt.internal.debug.eval.ast.instructions.SendMessage; 178 import org.eclipse.jdt.internal.debug.eval.ast.instructions.SendStaticMessage; 179 import org.eclipse.jdt.internal.debug.eval.ast.instructions.ThrowInstruction; 180 import org.eclipse.jdt.internal.debug.eval.ast.instructions.TwiddleOperator; 181 import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnaryMinusOperator; 182 import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnaryPlusOperator; 183 import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnsignedRightShiftAssignmentOperator; 184 import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnsignedRightShiftOperator; 185 import org.eclipse.jdt.internal.debug.eval.ast.instructions.Value; 186 import org.eclipse.jdt.internal.debug.eval.ast.instructions.XorAssignmentOperator; 187 import org.eclipse.jdt.internal.debug.eval.ast.instructions.XorOperator; 188 189 194 public class ASTInstructionCompiler extends ASTVisitor { 195 196 201 class CompleteInstruction { 202 Jump fInstruction; 203 String fLabel; 204 boolean fIsBreak; 205 206 public CompleteInstruction(Jump instruction, String label, boolean isBreak) { 207 fInstruction= instruction; 208 fLabel= label; 209 fIsBreak= isBreak; 210 } 211 } 212 213 216 private static boolean VERBOSE = false; 217 218 private InstructionSequence fInstructions; 219 220 223 private List fCompleteInstructions; 224 225 private int fStartPosition; 226 227 private boolean fActive; 228 229 private boolean fHasErrors; 230 231 private Stack fStack; 232 233 private int fCounter; 234 235 private int fUniqueIdIndex= 0; 237 238 239 242 public ASTInstructionCompiler(int startPosition, String snippet) { 243 fStartPosition = startPosition; 244 fInstructions = new InstructionSequence(snippet); 245 fStack = new Stack (); 246 fCompleteInstructions= new ArrayList (); 247 } 248 249 253 public InstructionSequence getInstructions() { 254 return fInstructions; 255 } 256 257 268 public boolean hasErrors() { 269 return fHasErrors; 270 } 271 272 private void setHasError(boolean value) { 273 fHasErrors= value; 274 } 275 276 private void addErrorMessage(String message) { 277 fInstructions.addError(message); 278 } 279 280 private boolean isActive() { 281 return fActive; 282 } 283 284 private void setActive(boolean active) { 285 fActive = active; 286 } 287 288 289 private void push(Instruction i) { 290 fStack.push(i); 291 } 292 293 private Instruction pop() { 294 return (Instruction)fStack.pop(); 295 } 296 297 private void storeInstruction() { 298 Instruction instruction= pop(); 299 fCounter++; 300 if (instruction instanceof CompoundInstruction) { 301 ((CompoundInstruction)instruction).setEnd(fCounter); 302 } 303 fInstructions.add(instruction); 304 verbose("Add " + instruction.toString()); } 306 307 308 314 private void verbose(String message) { 315 if (VERBOSE) { 316 System.out.println(message); 317 } 318 } 319 320 private String getTypeName(ITypeBinding typeBinding) { 321 if (typeBinding.isRawType()) { 322 typeBinding= typeBinding.getErasure(); 323 } 324 if (typeBinding.isTypeVariable()) { 325 ITypeBinding[] typeBounds= typeBinding.getTypeBounds(); 326 if (typeBounds.length > 0) { 327 String name= getTypeName(typeBounds[0]); 328 if (typeBounds.length > 1 && "java.lang.Object".equals(name)) { return getTypeName(typeBounds[1]); 330 } 331 return name; 332 } 333 return "java.lang.Object"; } 335 StringBuffer name; 336 if (typeBinding.isArray()) { 337 name= new StringBuffer (getTypeName(typeBinding.getElementType())); 338 int dimensions= typeBinding.getDimensions(); 339 for (int i= 0; i < dimensions; i++) { 340 name.append("[]"); } 342 return name.toString(); 343 } 344 String typeName= typeBinding.getName(); 345 int parameters= typeName.indexOf('<'); 346 if (parameters >= 0) { 347 typeName= typeName.substring(0, parameters); 348 } 349 name= new StringBuffer (typeName); 350 IPackageBinding packageBinding= typeBinding.getPackage(); 351 typeBinding= typeBinding.getDeclaringClass(); 352 while(typeBinding != null) { 353 name.insert(0, '$').insert(0, typeBinding.getName()); 354 typeBinding= typeBinding.getDeclaringClass(); 355 } 356 if (packageBinding != null && !packageBinding.isUnnamed()) { 357 name.insert(0, '.').insert(0, packageBinding.getName()); 358 } 359 return name.toString(); 360 } 361 362 private String getTypeSignature(ITypeBinding typeBinding) { 363 return Signature.createTypeSignature(getTypeName(typeBinding), true).replace('.', '/'); 364 } 365 366 private boolean isALocalType(ITypeBinding typeBinding) { 367 while(typeBinding != null) { 368 if (typeBinding.isLocal()) { 369 return true; 370 } 371 typeBinding= typeBinding.getDeclaringClass(); 372 } 373 return false; 374 } 375 376 private boolean containsALocalType(IMethodBinding methodBinding) { 377 ITypeBinding[] typeBindings= methodBinding.getParameterTypes(); 378 for (int i= 0, length= typeBindings.length; i < length; i++) { 379 if (isALocalType(typeBindings[i])) { 380 return true; 381 } 382 } 383 return false; 384 } 385 386 private int getEnclosingLevel(ASTNode node, ITypeBinding referenceTypeBinding) { 387 ASTNode parent= node; 388 do { 389 parent= parent.getParent(); 390 } while (!(parent instanceof TypeDeclaration || parent instanceof EnumDeclaration || parent instanceof AnonymousClassDeclaration)); 391 ITypeBinding parentBinding; 392 if (parent instanceof TypeDeclaration) { 393 parentBinding= ((TypeDeclaration)parent).resolveBinding(); 394 } else if (parent instanceof EnumDeclaration) { 395 parentBinding= ((EnumDeclaration)parent).resolveBinding(); 396 } else { 397 parentBinding= ((AnonymousClassDeclaration)parent).resolveBinding(); 398 } 399 if (parentBinding.isCastCompatible(referenceTypeBinding)) { 400 return 0; 401 } 402 return getEnclosingLevel(parent, referenceTypeBinding) + 1; 403 } 404 405 private int getSuperLevel(ITypeBinding current, ITypeBinding reference) { 406 if (current.equals(reference)) { 407 return 0; 408 } 409 return getSuperLevel(current.getSuperclass(), reference); 410 } 411 412 418 private String getLabel(Statement statement) { 419 ASTNode parent= statement.getParent(); 420 if (parent instanceof LabeledStatement) { 421 return ((LabeledStatement)parent).getLabel().getIdentifier(); 422 } 423 return null; 424 } 425 426 434 private void addPopInstructionIfNeeded(Expression expression) { 435 boolean pop= true; 436 437 if (expression instanceof MethodInvocation) { 438 IMethodBinding methodBinding= (IMethodBinding)((MethodInvocation)expression).getName().resolveBinding(); 439 if ("void".equals(methodBinding.getReturnType().getName())) { pop= false; 441 } 442 } else if (expression instanceof SuperMethodInvocation) { 443 IMethodBinding methodBinding= (IMethodBinding)((SuperMethodInvocation)expression).getName().resolveBinding(); 444 if ("void".equals(methodBinding.getReturnType().getName())) { pop= false; 446 } 447 } else if (expression instanceof VariableDeclarationExpression) { 448 pop= false; 449 } 450 451 if (pop) { 452 addPopInstruction(); 453 } 454 } 455 456 459 private void addPopInstruction() { 460 Instruction lastInstruction= fInstructions.getInstruction(fInstructions.getEnd()); 461 push(new Pop(lastInstruction.getSize() + 1)); 462 storeInstruction(); 463 } 464 465 470 private boolean checkAutoBoxing(ITypeBinding valueBinding, ITypeBinding requestedBinding) { 471 if (valueBinding.isPrimitive() == requestedBinding.isPrimitive()) { 472 return false; 473 } 474 if (requestedBinding.isPrimitive()) { 475 unBoxing(valueBinding); 476 } else { 477 boxing(requestedBinding, valueBinding); 478 } 479 return true; 480 } 481 482 485 private void boxing(ITypeBinding requestedBinding, ITypeBinding valueBinding) { 486 String requestedTypeName= requestedBinding.getQualifiedName(); 487 if ("java.lang.Object".equals(requestedTypeName)) { switch (valueBinding.getBinaryName().charAt(0)) { 489 case 'I': 490 push(new SendStaticMessage("java.lang.Integer", "valueOf", "(I)Ljava/lang/Integer;", 1, fCounter)); break; 492 case 'C': 493 push(new SendStaticMessage("java.lang.Character", "valueOf", "(C)Ljava/lang/Character;", 1, fCounter)); break; 495 case 'B': 496 push(new SendStaticMessage("java.lang.Byte", "valueOf", "(B)Ljava/lang/Byte;", 1, fCounter)); break; 498 case 'S': 499 push(new SendStaticMessage("java.lang.Short", "valueOf", "(S)Ljava/lang/Short;", 1, fCounter)); break; 501 case 'J': 502 push(new SendStaticMessage("java.lang.Long", "valueOf", "(J)Ljava/lang/Long;", 1, fCounter)); break; 504 case 'F': 505 push(new SendStaticMessage("java.lang.Float", "valueOf", "(F)Ljava/lang/Float;", 1, fCounter)); break; 507 case 'D': 508 push(new SendStaticMessage("java.lang.Double", "valueOf", "(D)Ljava/lang/Double;", 1, fCounter)); break; 510 case 'Z': 511 push(new SendStaticMessage("java.lang.Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", 1, fCounter)); break; 513 } 514 } else if ("java.lang.Integer".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(I)Ljava/lang/Integer;", 1, fCounter)); } else if ("java.lang.Character".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(C)Ljava/lang/Character;", 1, fCounter)); } else if ("java.lang.Byte".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(B)Ljava/lang/Byte;", 1, fCounter)); } else if ("java.lang.Short".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(S)Ljava/lang/Short;", 1, fCounter)); } else if ("java.lang.Long".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(J)Ljava/lang/Long;", 1, fCounter)); } else if ("java.lang.Float".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(F)Ljava/lang/Float;", 1, fCounter)); } else if ("java.lang.Double".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(D)Ljava/lang/Double;", 1, fCounter)); } else if ("java.lang.Boolean".equals(requestedTypeName)) { push(new SendStaticMessage(requestedTypeName, "valueOf", "(Z)Ljava/lang/Boolean;", 1, fCounter)); } 531 } 532 533 537 private boolean unBoxing(ITypeBinding valueBinding) { 538 String valueTypeName= valueBinding.getQualifiedName(); 539 if ("java.lang.Integer".equals(valueTypeName)) { push(new SendMessage("intValue", "()I", 0, null, fCounter)); } else if ("java.lang.Character".equals(valueTypeName)) { push(new SendMessage("charValue", "()C", 0, null, fCounter)); } else if ("java.lang.Byte".equals(valueTypeName)) { push(new SendMessage("byteValue", "()B", 0, null, fCounter)); } else if ("java.lang.Short".equals(valueTypeName)) { push(new SendMessage("shortValue", "()S", 0, null, fCounter)); } else if ("java.lang.Long".equals(valueTypeName)) { push(new SendMessage("longValue", "()J", 0, null, fCounter)); } else if ("java.lang.Float".equals(valueTypeName)) { push(new SendMessage("floatValue", "()F", 0, null, fCounter)); } else if ("java.lang.Double".equals(valueTypeName)) { push(new SendMessage("doubleValue", "()D", 0, null, fCounter)); } else if ("java.lang.Boolean".equals(valueTypeName)) { push(new SendMessage("booleanValue", "()Z", 0, null, fCounter)); } else { 556 return false; 557 } 558 return true; 559 } 560 561 574 575 578 public void endVisit(AnonymousClassDeclaration node) { 579 580 } 581 582 585 public void endVisit(ArrayAccess node) { 586 if (!isActive() || hasErrors()) 587 return; 588 storeInstruction(); 589 } 590 591 594 public void endVisit(ArrayCreation node) { 595 if (!isActive() || hasErrors()) 596 return; 597 storeInstruction(); 598 } 599 600 603 public void endVisit(ArrayInitializer node) { 604 if (!isActive() || hasErrors()) 605 return; 606 storeInstruction(); 607 } 608 609 612 public void endVisit(ArrayType node) { 613 if (!isActive() || hasErrors()) 614 return; 615 storeInstruction(); 616 } 617 618 621 public void endVisit(AssertStatement node) { 622 623 } 624 625 628 public void endVisit(Assignment node) { 629 if (!isActive() || hasErrors()) 630 return; 631 storeInstruction(); 632 } 633 634 637 public void endVisit(Block node) { 638 if (!isActive() || hasErrors()) 639 return; 640 storeInstruction(); 641 } 642 643 646 public void endVisit(BooleanLiteral node) { 647 if (!isActive() || hasErrors()) 648 return; 649 storeInstruction(); 650 } 651 652 655 public void endVisit(BreakStatement node) { 656 if (!isActive() || hasErrors()) 657 return; 658 storeInstruction(); 659 } 660 661 664 public void endVisit(CastExpression node) { 665 if (!isActive() || hasErrors()) 666 return; 667 storeInstruction(); 668 } 669 670 673 public void endVisit(CatchClause node) { 674 675 } 676 677 680 public void endVisit(CharacterLiteral node) { 681 if (!isActive() || hasErrors()) 682 return; 683 storeInstruction(); 684 } 685 686 689 public void endVisit(ClassInstanceCreation node) { 690 if (!isActive() || hasErrors()) 691 return; 692 storeInstruction(); 693 } 694 695 698 public void endVisit(CompilationUnit node) { 699 700 } 701 702 705 public void endVisit(ConditionalExpression node) { 706 if (!isActive() || hasErrors()) 707 return; 708 709 int ifFalseAddress= fInstructions.getEnd(); 711 Instruction ifFalse= fInstructions.get(ifFalseAddress); 712 int ifTrueAddress= ifFalseAddress - ifFalse.getSize(); 713 Instruction ifTrue= fInstructions.get(ifTrueAddress); 714 int conditionalAddress= ifTrueAddress - ifTrue.getSize(); 715 716 ConditionalJump conditionalJump= new ConditionalJump(false); 718 fInstructions.insert(conditionalJump, conditionalAddress + 1); 719 720 int jumpAddress= ifTrueAddress + 2; 722 Jump jump= new Jump(); 723 fInstructions.insert(jump, jumpAddress); 724 725 conditionalJump.setOffset(ifTrue.getSize() + 1); 727 jump.setOffset(ifFalse.getSize() + 1); 728 729 fCounter += 2; 730 storeInstruction(); 731 732 } 733 734 737 public void endVisit(ConstructorInvocation node) { 738 739 } 740 741 744 public void endVisit(ContinueStatement node) { 745 if (!isActive() || hasErrors()) 746 return; 747 storeInstruction(); 748 } 749 750 753 public void endVisit(DoStatement node) { 754 if (!isActive() || hasErrors()) 755 return; 756 757 768 769 String label= getLabel(node); 770 771 int conditionAddress= fInstructions.getEnd(); 773 Instruction condition= fInstructions.getInstruction(conditionAddress); 774 int bodyAddress= conditionAddress - condition.getSize(); 775 Instruction body= fInstructions.getInstruction(bodyAddress); 776 int bodyStartAddress= bodyAddress - body.getSize(); 777 778 ConditionalJump conditionalJump= new ConditionalJump(true); 780 fInstructions.add(conditionalJump); 781 fCounter++; 782 783 conditionalJump.setOffset(-(condition.getSize() + body.getSize() + 1)); 785 786 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 789 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 790 Jump jumpInstruction= instruction.fInstruction; 791 int instructionAddress= fInstructions.indexOf(jumpInstruction); 792 if (instructionAddress > bodyStartAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) { 793 iter.remove(); 794 if (instruction.fIsBreak) { 795 jumpInstruction.setOffset((conditionAddress - instructionAddress) + 1); 797 } else { 798 jumpInstruction.setOffset(bodyAddress - instructionAddress); 800 } 801 } 802 } 803 804 storeInstruction(); 805 } 806 807 810 public void endVisit(EmptyStatement node) { 811 if (!isActive() || hasErrors()) 812 return; 813 storeInstruction(); 814 } 815 816 819 public void endVisit(EnhancedForStatement node) { 820 if (!isActive() || hasErrors()) 821 return; 822 823 859 860 int bodyAddress= fInstructions.getEnd(); 861 Instruction body= fInstructions.getInstruction(bodyAddress); 862 int conditionAddress= bodyAddress - body.getSize(); 863 Instruction condition= fInstructions.getInstruction(conditionAddress); 864 int initAddress= conditionAddress - condition.getSize(); 865 866 ConditionalJump condJump= new ConditionalJump(false); 868 fInstructions.insert(condJump, conditionAddress + 1); 869 bodyAddress++; 870 fCounter++; 871 condJump.setOffset(body.getSize() + 1); 872 873 Jump jump= new Jump(); 875 fInstructions.add(jump); 876 fCounter++; 877 jump.setOffset(initAddress - (bodyAddress + 1)); 878 879 880 String label= getLabel(node); 883 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 884 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 885 Jump jumpInstruction= instruction.fInstruction; 886 int instructionAddress= fInstructions.indexOf(jumpInstruction); 887 if (instructionAddress > conditionAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) { 888 iter.remove(); 889 if (instruction.fIsBreak) { 890 jumpInstruction.setOffset((bodyAddress - instructionAddress) + 1); 892 } else { 893 jumpInstruction.setOffset(initAddress - instructionAddress); 895 } 896 } 897 } 898 899 storeInstruction(); 900 } 901 902 905 public void endVisit(ExpressionStatement node) { 906 if (!isActive() || hasErrors()) 907 return; 908 909 addPopInstructionIfNeeded(node.getExpression()); 910 } 911 912 915 public void endVisit(FieldAccess node) { 916 if (!isActive() || hasErrors()) 917 return; 918 storeInstruction(); 919 } 920 921 924 public void endVisit(FieldDeclaration node) { 925 926 } 927 928 931 public void endVisit(ForStatement node) { 932 if (!isActive() || hasErrors()) 933 return; 934 935 953 954 String label= getLabel(node); 955 boolean hasCondition= node.getExpression() != null; 956 957 int updatersAddress= fInstructions.getEnd(); 959 Instruction updaters= fInstructions.getInstruction(updatersAddress); 960 int bodyAddress= updatersAddress - updaters.getSize(); 961 Instruction body= fInstructions.getInstruction(bodyAddress); 962 int bodyStartAddress= bodyAddress - body.getSize(); 963 964 int conditionAddress; 965 Instruction condition; 966 967 if (hasCondition) { 968 conditionAddress= bodyStartAddress; 969 condition= fInstructions.getInstruction(conditionAddress); 970 } else { 971 conditionAddress= 0; 972 condition= null; 973 } 974 975 Jump jump= new Jump(); 977 fInstructions.add(jump); 978 fCounter++; 979 980 if (hasCondition) { 981 ConditionalJump condJump= new ConditionalJump(false); 983 fInstructions.insert(condJump, conditionAddress + 1); 984 bodyAddress++; 985 bodyStartAddress++; 986 updatersAddress++; 987 fCounter++; 988 condJump.setOffset(body.getSize() + updaters.getSize() + 1); 990 } 991 992 jump.setOffset(-((hasCondition ? condition.getSize() : 0) + body.getSize() + updaters.getSize() + 2)); 994 995 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 998 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 999 Jump jumpInstruction= instruction.fInstruction; 1000 int instructionAddress= fInstructions.indexOf(jumpInstruction); 1001 if (instructionAddress > bodyStartAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) { 1002 iter.remove(); 1003 if (instruction.fIsBreak) { 1004 jumpInstruction.setOffset((updatersAddress - instructionAddress) + 1); 1006 } else { 1007 jumpInstruction.setOffset(bodyAddress - instructionAddress); 1009 } 1010 } 1011 } 1012 1013 storeInstruction(); 1014 } 1015 1016 1019 public void endVisit(IfStatement node) { 1020 if (!isActive() || hasErrors()) 1021 return; 1022 1023 boolean hasElseStatement= node.getElseStatement() != null; 1024 1025 1027 int ifFalseAddress= 0; 1028 Instruction ifFalse= null; 1029 int ifTrueAddress= 0; 1030 Instruction ifTrue= null; 1031 1032 if (hasElseStatement) { 1033 ifFalseAddress= fInstructions.getEnd(); 1034 ifFalse= fInstructions.get(ifFalseAddress); 1035 ifTrueAddress= ifFalseAddress - ifFalse.getSize(); 1036 ifTrue= fInstructions.get(ifTrueAddress); 1037 } else { 1038 ifTrueAddress= fInstructions.getEnd(); 1039 ifTrue= fInstructions.get(ifTrueAddress); 1040 } 1041 1042 int conditionalAddress= ifTrueAddress - ifTrue.getSize(); 1043 1044 ConditionalJump conditionalJump= new ConditionalJump(false); 1046 fInstructions.insert(conditionalJump, conditionalAddress + 1); 1047 conditionalJump.setOffset(ifTrue.getSize() + ((hasElseStatement)? 1 : 0)); 1049 fCounter++; 1050 1051 if (hasElseStatement) { 1052 int jumpAddress= ifTrueAddress + 2; 1054 Jump jump= new Jump(); 1055 fInstructions.insert(jump, jumpAddress); 1056 jump.setOffset(ifFalse.getSize() + 1); 1058 fCounter++; 1059 } 1060 1061 storeInstruction(); 1062 1063 } 1064 1065 1068 public void endVisit(ImportDeclaration node) { 1069 1070 } 1071 1072 1075 public void endVisit(InfixExpression node) { 1076 } 1077 1078 1081 public void endVisit(Initializer node) { 1082 1083 } 1084 1085 1088 public void endVisit(InstanceofExpression node) { 1089 if (!isActive() || hasErrors()) 1090 return; 1091 storeInstruction(); 1092 } 1093 1094 1097 public void endVisit(Javadoc node) { 1098 1099 } 1100 1101 1104 public void endVisit(LabeledStatement node) { 1105 if (!isActive() || hasErrors()) 1106 return; 1107 1108 String label= node.getLabel().getIdentifier(); 1109 1110 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 1113 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 1114 if (instruction.fLabel != null && instruction.fLabel.equals(label)) { 1115 iter.remove(); 1116 Jump jumpInstruction= instruction.fInstruction; 1117 int instructionAddress= fInstructions.indexOf(jumpInstruction); 1118 if (instruction.fIsBreak) { 1119 jumpInstruction.setOffset(fInstructions.getEnd() - instructionAddress); 1121 } 1122 } 1123 } 1124 } 1125 1126 1129 public void endVisit(MethodDeclaration node) { 1130 setActive(false); 1131 } 1132 1133 1136 public void endVisit(MethodInvocation node) { 1137 if (!isActive() || hasErrors()) 1138 return; 1139 storeInstruction(); 1140 } 1141 1142 1145 public void endVisit(NullLiteral node) { 1146 if (!isActive() || hasErrors()) 1147 return; 1148 storeInstruction(); 1149 } 1150 1151 1154 public void endVisit(NumberLiteral node) { 1155 if (!isActive() || hasErrors()) 1156 return; 1157 storeInstruction(); 1158 } 1159 1160 1163 public void endVisit(PackageDeclaration node) { 1164 1165 } 1166 1167 1170 public void endVisit(ParameterizedType node) { 1171 if (!isActive() || hasErrors()) 1172 return; 1173 storeInstruction(); 1174 } 1175 1176 1179 public void endVisit(ParenthesizedExpression node) { 1180 1181 } 1182 1183 1186 public void endVisit(PostfixExpression node) { 1187 if (!isActive() || hasErrors()) 1188 return; 1189 storeInstruction(); 1190 } 1191 1192 1195 public void endVisit(PrefixExpression node) { 1196 if (!isActive() || hasErrors()) 1197 return; 1198 storeInstruction(); 1199 } 1200 1201 1204 public void endVisit(PrimitiveType node) { 1205 } 1206 1207 1210 public void endVisit(QualifiedName node) { 1211 } 1212 1213 1216 public void endVisit(QualifiedType node) { 1217 if (!isActive() || hasErrors()) 1218 return; 1219 storeInstruction(); 1220 } 1221 1222 1225 public void endVisit(ReturnStatement node) { 1226 if (!isActive() || hasErrors()) 1227 return; 1228 storeInstruction(); 1229 } 1230 1231 1234 public void endVisit(SimpleName node) { 1235 if (!isActive() || hasErrors()) 1236 return; 1237 storeInstruction(); 1238 } 1239 1240 1243 public void endVisit(SimpleType node) { 1244 if (!isActive() || hasErrors()) 1245 return; 1246 storeInstruction(); 1247 } 1248 1249 1252 public void endVisit(SingleVariableDeclaration node) { 1253 if (!isActive() || hasErrors()) 1254 return; 1255 storeInstruction(); 1256 } 1257 1258 1261 public void endVisit(StringLiteral node) { 1262 if (!isActive() || hasErrors()) 1263 return; 1264 storeInstruction(); 1265 } 1266 1267 1270 public void endVisit(SuperConstructorInvocation node) { 1271 1272 } 1273 1274 1277 public void endVisit(SuperFieldAccess node) { 1278 if (!isActive() || hasErrors()) 1279 return; 1280 storeInstruction(); 1281 } 1282 1283 1286 public void endVisit(SuperMethodInvocation node) { 1287 if (!isActive() || hasErrors()) 1288 return; 1289 storeInstruction(); 1290 } 1291 1292 1295 public void endVisit(SwitchCase node) { 1296 } 1298 1299 1302 public void endVisit(SwitchStatement node) { 1303 } 1305 1306 1309 public void endVisit(SynchronizedStatement node) { 1310 1311 } 1312 1313 1316 public void endVisit(ThisExpression node) { 1317 if (!isActive() || hasErrors()) 1318 return; 1319 storeInstruction(); 1320 } 1321 1322 1325 public void endVisit(ThrowStatement node) { 1326 if (!isActive() || hasErrors()) 1327 return; 1328 storeInstruction(); 1329 } 1330 1331 1334 public void endVisit(TryStatement node) { 1335 1336 } 1337 1338 1341 public void endVisit(TypeDeclaration node) { 1342 1343 } 1344 1345 1348 public void endVisit(TypeDeclarationStatement node) { 1349 1350 } 1351 1352 1355 public void endVisit(TypeLiteral node) { 1356 if (!isActive() || hasErrors()) 1357 return; 1358 storeInstruction(); 1359 } 1360 1361 1364 public void endVisit(VariableDeclarationExpression node) { 1365 1366 } 1367 1368 1371 public void endVisit(VariableDeclarationFragment node) { 1372 if (!isActive() || hasErrors()) 1373 return; 1374 storeInstruction(); 1375 } 1376 1377 1380 public void endVisit(VariableDeclarationStatement node) { 1381 1382 } 1383 1384 1387 public void endVisit(WhileStatement node) { 1388 if (!isActive() || hasErrors()) 1389 return; 1390 1391 1403 1404 String label= getLabel(node); 1405 1406 int bodyAddress= fInstructions.getEnd(); 1408 Instruction body= fInstructions.getInstruction(bodyAddress); 1409 int conditionAddress= bodyAddress - body.getSize(); 1410 Instruction condition= fInstructions.getInstruction(conditionAddress); 1411 1412 ConditionalJump conditionalJump= new ConditionalJump(false); 1414 fInstructions.insert(conditionalJump, conditionAddress + 1); 1415 1416 Jump jump= new Jump(); 1418 fInstructions.add(jump); 1419 1420 conditionalJump.setOffset(body.getSize() + 1); 1422 jump.setOffset(-(condition.getSize() + body.getSize() + 2)); 1423 1424 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 1427 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 1428 Jump jumpInstruction= instruction.fInstruction; 1429 int instructionAddress= fInstructions.indexOf(jumpInstruction); 1430 if (instructionAddress > conditionAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) { 1431 iter.remove(); 1432 if (instruction.fIsBreak) { 1433 jumpInstruction.setOffset((bodyAddress - instructionAddress) + 2); 1435 } else { 1436 jumpInstruction.setOffset((conditionAddress - condition.getSize()) - instructionAddress); 1438 } 1439 } 1440 } 1441 1442 fCounter+= 2; 1443 storeInstruction(); 1444 } 1445 1446 1460 1461 1464 public boolean visit(AnnotationTypeDeclaration node) { 1465 return false; 1466 } 1467 1468 1471 public boolean visit(AnnotationTypeMemberDeclaration node) { 1472 return false; 1473 } 1474 1475 1478 public boolean visit(AnonymousClassDeclaration node) { 1479 if (!isActive()) { 1480 return true; 1481 } 1482 setHasError(true); 1483 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_2); 1484 return false; 1485 } 1486 1487 1490 public boolean visit(ArrayAccess node) { 1491 if (!isActive()) { 1492 return false; 1493 } 1494 1495 push(new org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAccess(fCounter)); 1496 1497 return true; 1498 } 1499 1500 1503 public boolean visit(ArrayCreation node) { 1504 if (!isActive()) { 1505 return false; 1506 } 1507 1508 ArrayType arrayType= node.getType(); 1509 1510 if (isALocalType(arrayType.resolveBinding().getElementType())) { 1511 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Local_type_array_instance_creation_cannot_be_used_in_an_evaluation_expression_29); 1512 setHasError(true); 1513 return true; 1514 } 1515 1516 push(new ArrayAllocation(arrayType.getDimensions(), node.dimensions().size(), node.getInitializer() != null, fCounter)); 1517 1518 return true; 1519 } 1520 1521 1524 public boolean visit(ArrayInitializer node) { 1525 if (!isActive()) { 1526 return false; 1527 } 1528 1529 ITypeBinding typeBinding= node.resolveTypeBinding(); 1530 int dimension= typeBinding.getDimensions(); 1531 String signature= getTypeSignature(typeBinding.getElementType()); 1532 1533 push(new ArrayInitializerInstruction(signature, node.expressions().size(), dimension, fCounter)); 1534 1535 return true; 1536 } 1537 1538 1541 public boolean visit(ArrayType node) { 1542 if (!isActive()) { 1543 return false; 1544 } 1545 ITypeBinding arrayTypeBinding= node.resolveBinding(); 1546 int dimension= arrayTypeBinding.getDimensions(); 1547 String signature= getTypeSignature(arrayTypeBinding.getElementType()); 1548 1549 push(new PushArrayType(signature, dimension, fCounter)); 1550 1551 return false; 1552 } 1553 1554 1557 public boolean visit(AssertStatement node) { 1558 if (!isActive()) { 1559 return false; 1560 } 1561 setHasError(true); 1562 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Assert_statement_cannot_be_used_in_an_evaluation_expression_3); 1563 return true; 1564 } 1565 1566 1569 public boolean visit(Assignment node) { 1570 if (!isActive()) { 1571 return false; 1572 } 1573 Expression leftHandSide= node.getLeftHandSide(); 1574 Expression rightHandSide= node.getRightHandSide(); 1575 int variableTypeId = getTypeId(leftHandSide); 1576 int valueTypeId = getTypeId(rightHandSide); 1577 1578 String opToken = node.getOperator().toString(); 1579 int opTokenLength = opToken.length(); 1580 char char0 = opToken.charAt(0); 1581 char char2 = '\0'; 1582 if (opTokenLength > 2) { 1583 char2 = opToken.charAt(2); 1584 } 1585 1586 if (variableTypeId == Instruction.T_Object) { 1587 1593 int unboxedVariableTypeId= getUnBoxedTypeId(leftHandSide); 1594 int unboxedValueTypeId= getUnBoxedTypeId(rightHandSide); 1595 int unboxedResultTypeId= Instruction.getBinaryPromotionType(unboxedVariableTypeId, unboxedValueTypeId); 1596 1597 push(new AssignmentOperator(variableTypeId, variableTypeId, fCounter)); 1598 1599 leftHandSide.accept(this); 1600 1601 if (char0 == '=') { 1602 1603 boolean storeRequired= false; 1604 if (rightHandSide.resolveTypeBinding().isPrimitive()) { 1605 boxing(leftHandSide.resolveTypeBinding(), rightHandSide.resolveTypeBinding()); 1606 storeRequired= true; 1607 } 1608 rightHandSide.accept(this); 1609 if (storeRequired) { 1610 storeInstruction(); } 1612 1613 } else { 1614 boolean unrecognized = false; 1615 1616 1617 boxing(leftHandSide.resolveTypeBinding(), rightHandSide.resolveTypeBinding()); 1618 1619 switch (char0) { 1620 case '=': break; 1622 case '+': push(new PlusOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1624 break; 1625 case '-': push(new MinusOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1627 break; 1628 case '*': push(new MultiplyOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1630 break; 1631 case '/': push(new DivideOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1633 break; 1634 case '%': push(new RemainderOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1636 break; 1637 case '^': push(new XorOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1639 break; 1640 case '|': push(new OrOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1642 break; 1643 case '&': push(new AndOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1645 break; 1646 case '<': push(new LeftShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1648 break; 1649 case '>': switch (char2) { 1651 case '=': push(new RightShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1653 break; 1654 case '>': push(new UnsignedRightShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter)); 1656 break; 1657 default: 1658 unrecognized = true; 1659 break; 1660 } 1661 break; 1662 default: 1663 unrecognized = true; 1664 break; 1665 } 1666 1667 if (unrecognized) { 1668 setHasError(true); 1669 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_assignment_operator____4 + opToken); 1670 return false; 1671 } 1672 1673 unBoxing(leftHandSide.resolveTypeBinding()); 1674 push(new Dup()); 1675 storeInstruction(); storeInstruction(); 1678 boolean storeRequired= unBoxing(rightHandSide.resolveTypeBinding()); 1679 rightHandSide.accept(this); 1680 if (storeRequired) { 1681 storeInstruction(); } 1683 1684 storeInstruction(); storeInstruction(); 1687 } 1688 1689 } else { 1690 boolean unrecognized = false; 1691 1692 switch (char0) { 1693 case '=': push(new AssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1695 break; 1696 case '+': push(new PlusAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1698 break; 1699 case '-': push(new MinusAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1701 break; 1702 case '*': push(new MultiplyAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1704 break; 1705 case '/': push(new DivideAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1707 break; 1708 case '%': push(new RemainderAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1710 break; 1711 case '^': push(new XorAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1713 break; 1714 case '|': push(new OrAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1716 break; 1717 case '&': push(new AndAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1719 break; 1720 case '<': push(new LeftShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1722 break; 1723 case '>': switch (char2) { 1725 case '=': push(new RightShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1727 break; 1728 case '>': push(new UnsignedRightShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter)); 1730 break; 1731 default: 1732 unrecognized = true; 1733 break; 1734 } 1735 break; 1736 default: 1737 unrecognized = true; 1738 break; 1739 } 1740 1741 if (unrecognized) { 1742 setHasError(true); 1743 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_assignment_operator____4 + opToken); 1744 return false; 1745 } 1746 1747 leftHandSide.accept(this); 1748 boolean storeRequired= unBoxing(rightHandSide.resolveTypeBinding()); 1749 rightHandSide.accept(this); 1750 if (storeRequired) { 1751 storeInstruction(); 1752 } 1753 } 1754 1755 return false; 1756 1757 } 1758 1759 1762 public boolean visit(Block node) { 1763 int start= node.getStartPosition(); 1764 if (start == fStartPosition || start == (fStartPosition + 1)) { 1765 setActive(true); 1766 } 1767 if (!isActive()) { 1768 return true; 1769 } 1770 1771 push(new NoOp(fCounter)); 1772 1773 return true; 1774 } 1775 1776 1779 public boolean visit(BlockComment node) { 1780 return false; 1781 } 1782 1783 1786 public boolean visit(BooleanLiteral node) { 1787 if (!isActive()) { 1788 return false; 1789 } 1790 1791 push(new PushBoolean(node.booleanValue())); 1792 1793 return true; 1794 } 1795 1796 1799 public boolean visit(BreakStatement node) { 1800 if (!isActive()) { 1801 return false; 1802 } 1803 Jump instruction= new Jump(); 1807 SimpleName labelName= node.getLabel(); 1808 String label= null; 1809 if (labelName != null) { 1810 label= labelName.getIdentifier(); 1811 } 1812 push(instruction); 1813 fCompleteInstructions.add(new CompleteInstruction(instruction, label, true)); 1814 1815 return false; 1816 } 1817 1818 1821 public boolean visit(CastExpression node) { 1822 if (!isActive()) { 1823 return false; 1824 } 1825 1826 Type type= node.getType(); 1827 int typeId= getTypeId(type); 1828 ITypeBinding typeBinding= type.resolveBinding(); 1829 1830 String baseTypeSignature; 1831 int dimension= typeBinding.getDimensions(); 1832 1833 if (typeBinding.isArray()) { 1834 typeBinding= typeBinding.getElementType(); 1835 } 1836 1837 baseTypeSignature= getTypeName(typeBinding); 1838 1839 push(new Cast(typeId, baseTypeSignature, dimension, fCounter)); 1840 1841 node.getExpression().accept(this); 1842 1843 return false; 1844 } 1845 1846 1849 public boolean visit(CatchClause node) { 1850 if (!isActive()) { 1851 return false; 1852 } 1853 setHasError(true); 1854 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Catch_clause_cannot_be_used_in_an_evaluation_expression_6); 1855 return true; 1856 } 1857 1858 1861 public boolean visit(CharacterLiteral node) { 1862 if (!isActive()) { 1863 return false; 1864 } 1865 1866 push(new PushChar(node.charValue())); 1867 1868 return true; 1869 } 1870 1871 1875 public boolean visit(ClassInstanceCreation node) { 1876 if (!isActive()) { 1877 return true; 1878 } 1879 1880 if (node.getAnonymousClassDeclaration() != null) { 1881 setHasError(true); 1882 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_7); 1883 } 1884 1885 IMethodBinding methodBinding= node.resolveConstructorBinding(); 1886 ITypeBinding typeBinding= methodBinding.getDeclaringClass(); 1887 ITypeBinding enclosingTypeBinding= typeBinding.getDeclaringClass(); 1888 1889 boolean isInstanceMemberType= typeBinding.isMember() && ! Modifier.isStatic(typeBinding.getModifiers()); 1890 1891 if (isALocalType(typeBinding)) { 1892 setHasError(true); 1893 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Constructor_of_a_local_type_cannot_be_used_in_an_evaluation_expression_8); 1894 } 1895 1896 if (containsALocalType(methodBinding)) { 1897 setHasError(true); 1898 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Constructor_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_30); 1899 } 1900 1901 1902 if (hasErrors()) { 1903 return true; 1904 } 1905 1906 int argCount= methodBinding.getParameterTypes().length; 1907 1908 String enclosingTypeSignature= null; 1909 if (isInstanceMemberType) { 1910 enclosingTypeSignature= getTypeSignature(enclosingTypeBinding); 1911 argCount++; 1912 } 1913 1914 String signature= getMethodSignature(methodBinding, enclosingTypeSignature).replace('.','/'); 1915 1916 push(new Constructor(signature, argCount, fCounter)); 1917 1918 push(new PushType(getTypeName(typeBinding))); 1919 storeInstruction(); 1920 1921 if (isInstanceMemberType) { 1922 Expression optionalExpression= node.getExpression(); 1923 if (optionalExpression != null) { 1924 optionalExpression.accept(this); 1925 } else { 1926 ASTNode parent= node; 1928 do { 1929 parent= parent.getParent(); 1930 } while (! (parent instanceof MethodDeclaration)); 1931 if (Modifier.isStatic(((MethodDeclaration)parent).getModifiers())) { 1932 setHasError(true); 1933 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Must_explicitly_qualify_the_allocation_with_an_instance_of_the_enclosing_type_33); 1934 return true; 1935 } 1936 1937 push(new PushThis(getEnclosingLevel(node, enclosingTypeBinding))); 1938 storeInstruction(); 1939 } 1940 } 1941 1942 Iterator iterator= node.arguments().iterator(); 1943 while (iterator.hasNext()) { 1944 ((Expression) iterator.next()).accept(this); 1945 } 1946 1947 return false; 1948 } 1949 1950 1953 public boolean visit(CompilationUnit node) { 1954 return true; 1955 } 1956 1957 1960 public boolean visit(ConditionalExpression node) { 1961 if (!isActive()) { 1962 return true; 1963 } 1964 1965 push(new NoOp(fCounter)); 1966 1967 return true; 1968 } 1969 1970 1973 public boolean visit(ConstructorInvocation node) { 1974 if (!isActive()) { 1975 return false; 1976 } 1977 setHasError(true); 1978 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_this_constructor_invocation_cannot_be_used_in_an_evaluation_expression_9); 1979 return false; 1980 } 1981 1982 1985 public boolean visit(ContinueStatement node) { 1986 if (!isActive()) { 1987 return false; 1988 } 1989 Jump instruction= new Jump(); 1993 SimpleName labelName= node.getLabel(); 1994 String label= null; 1995 if (labelName != null) { 1996 label= labelName.getIdentifier(); 1997 } 1998 push(instruction); 1999 fCompleteInstructions.add(new CompleteInstruction(instruction, label, false)); 2000 2001 return false; 2002 } 2003 2004 2007 public boolean visit(DoStatement node) { 2008 if (!isActive()) { 2009 return false; 2010 } 2011 2012 push(new NoOp(fCounter)); 2013 return true; 2014 } 2015 2016 2019 public boolean visit(EmptyStatement node) { 2020 if (!isActive()) { 2021 return false; 2022 } 2023 push(new NoOp(fCounter)); 2024 return true; 2025 } 2026 2027 2030 public boolean visit(EnhancedForStatement node) { 2031 if (!isActive()) { 2032 return false; 2033 } 2034 2035 push(new NoOp(fCounter)); 2036 2037 2038 ITypeBinding typeBinding= node.getExpression().resolveTypeBinding(); 2039 Type paramType= node.getParameter().getType(); 2040 ITypeBinding paramBinding = paramType.resolveBinding(); 2041 String typeSignature= getTypeSignature(paramBinding); 2042 int paramTypeId= getTypeId(paramType); 2043 boolean isParamPrimitiveType= paramTypeId != Instruction.T_Object && paramTypeId != Instruction.T_String; 2044 String paramIdentifier= node.getParameter().getName().getIdentifier(); 2045 2046 if (typeBinding.isArray()) { 2047 int idIndex= fUniqueIdIndex++; 2049 String arrayIdentifier= "#a" + idIndex; String varIdentifier= "#i" + idIndex; push(new LocalVariableCreation(arrayIdentifier, typeSignature, 1, isParamPrimitiveType, true, fCounter)); 2052 node.getExpression().accept(this); 2053 storeInstruction(); 2054 push(new LocalVariableCreation(varIdentifier, "I", 0, true, true, fCounter)); push(new PushInt(0)); 2056 storeInstruction(); 2057 storeInstruction(); 2058 push(new LocalVariableCreation(paramIdentifier, typeSignature, 0, isParamPrimitiveType, false, fCounter)); 2059 storeInstruction(); 2060 2061 push(new LessOperator(Instruction.T_int, Instruction.T_int, fCounter)); 2062 push(new PushLocalVariable(varIdentifier)); 2063 storeInstruction(); 2064 push(new PushArrayLength(fCounter)); 2065 push(new PushLocalVariable(arrayIdentifier)); 2066 storeInstruction(); 2067 storeInstruction(); 2068 storeInstruction(); 2069 2070 2072 push(new NoOp(fCounter)); 2073 push(new AssignmentOperator(paramTypeId, paramTypeId, fCounter)); 2074 push(new PushLocalVariable(paramIdentifier)); 2075 storeInstruction(); 2076 push(new org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAccess(fCounter)); 2077 push(new PushLocalVariable(arrayIdentifier)); 2078 storeInstruction(); 2079 push(new PostfixPlusPlusOperator(Instruction.T_int, fCounter)); 2080 push(new PushLocalVariable(varIdentifier)); 2081 storeInstruction(); 2082 storeInstruction(); 2083 storeInstruction(); 2084 if (checkAutoBoxing(typeBinding.getElementType(), paramBinding)) { 2085 storeInstruction(); 2086 } 2087 storeInstruction(); 2088 addPopInstruction(); 2089 node.getBody().accept(this); 2090 storeInstruction(); 2091 2092 2094 } else { 2095 String iteratorIdentifier= "#i" + fUniqueIdIndex++; push(new LocalVariableCreation(iteratorIdentifier, "Ljava/util/Iterator;", 0, false, true, fCounter)); push(new SendMessage("iterator", "()Ljava/util/Iterator;", 0, null, fCounter)); node.getExpression().accept(this); 2100 storeInstruction(); 2101 storeInstruction(); 2102 push(new LocalVariableCreation(paramIdentifier, typeSignature, 0, isParamPrimitiveType, false, fCounter)); 2103 storeInstruction(); 2104 2105 push(new SendMessage("hasNext", "()Z", 0, null, fCounter)); push(new PushLocalVariable(iteratorIdentifier)); 2107 storeInstruction(); 2108 storeInstruction(); 2109 2110 2112 push(new NoOp(fCounter)); 2113 push(new AssignmentOperator(paramTypeId, paramTypeId, fCounter)); 2114 push(new PushLocalVariable(paramIdentifier)); 2115 storeInstruction(); 2116 push(new SendMessage("next", "()Ljava/lang/Object;", 0, null, fCounter)); push(new PushLocalVariable(iteratorIdentifier)); 2118 storeInstruction(); 2119 storeInstruction(); 2120 if (checkAutoBoxing(typeBinding.getTypeArguments()[0], paramBinding)) { 2121 storeInstruction(); 2122 } 2123 storeInstruction(); 2124 addPopInstruction(); 2125 node.getBody().accept(this); 2126 storeInstruction(); 2127 2128 2130 } 2131 2132 return false; 2133 } 2134 2135 2138 public boolean visit(EnumConstantDeclaration node) { 2139 if (!isActive()) { 2140 return true; 2141 } 2142 2143 return false; 2145 } 2146 2147 2150 public boolean visit(EnumDeclaration node) { 2151 if (!isActive()) { 2152 return true; 2153 } 2154 setHasError(true); 2155 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_0); 2156 return false; 2157 } 2158 2159 2162 public boolean visit(ExpressionStatement node) { 2163 return true; 2164 } 2165 2166 2171 public boolean visit(FieldAccess node) { 2172 if (!isActive()) { 2173 return false; 2174 } 2175 2176 SimpleName fieldName= node.getName(); 2177 IVariableBinding fieldBinding= (IVariableBinding) fieldName.resolveBinding(); 2178 ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass(); 2179 Expression expression = node.getExpression(); 2180 String fieldId = fieldName.getIdentifier(); 2181 2182 if (Modifier.isStatic(fieldBinding.getModifiers())) { 2183 push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter)); 2184 expression.accept(this); 2185 addPopInstruction(); 2186 } else { 2187 if (declaringTypeBinding == null) { push(new PushArrayLength(fCounter)); 2189 } else { 2190 if (isALocalType(declaringTypeBinding)) { 2191 setHasError(true); 2192 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Qualified_local_type_field_access_cannot_be_used_in_an_evaluation_expression_31); 2193 return false; 2194 } 2195 push(new PushFieldVariable(fieldId, getTypeSignature(declaringTypeBinding), fCounter)); 2196 } 2197 expression.accept(this); 2198 } 2199 2200 return false; 2201 } 2202 2203 2206 public boolean visit(FieldDeclaration node) { 2207 return true; 2208 } 2209 2210 2216 public boolean visit(ForStatement node) { 2217 if (!isActive()) { 2218 return false; 2219 } 2220 2221 push(new NoOp(fCounter)); 2222 2223 push(new NoOp(fCounter)); 2224 for (Iterator iter= node.initializers().iterator(); iter.hasNext();) { 2225 Expression expr= (Expression) iter.next(); 2226 expr.accept(this); 2227 addPopInstructionIfNeeded(expr); 2228 } 2229 storeInstruction(); 2230 2231 Expression condition= node.getExpression(); 2232 if (condition != null) { 2233 condition.accept(this); 2234 } 2235 2236 node.getBody().accept(this); 2237 2238 push(new NoOp(fCounter)); 2239 for (Iterator iter= node.updaters().iterator(); iter.hasNext();) { 2240 Expression expr= (Expression) iter.next(); 2241 expr.accept(this); 2242 addPopInstructionIfNeeded(expr); 2243 } 2244 storeInstruction(); 2245 2246 return false; 2247 } 2248 2249 2252 public boolean visit(IfStatement node) { 2253 if (!isActive()) { 2254 return false; 2255 } 2256 2257 push(new NoOp(fCounter)); 2258 2259 return true; 2260 } 2261 2262 2265 public boolean visit(ImportDeclaration node) { 2266 return false; 2267 } 2268 2269 2274 public boolean visit(InfixExpression node) { 2275 if (!isActive()) { 2276 return false; 2277 } 2278 2279 String opToken = node.getOperator().toString(); 2280 int opTokenLength = opToken.length(); 2281 char char0 = opToken.charAt(0); 2282 char char1 = '\0'; 2283 char char2 = '\0'; 2284 if (opTokenLength > 1) { 2285 char1 = opToken.charAt(1); 2286 if (opTokenLength > 2) { 2287 char2 = opToken.charAt(2); 2288 } 2289 } 2290 2291 List extendedOperands = node.extendedOperands(); 2292 2293 int operatorNumber=extendedOperands.size() + 1; 2294 2295 int[][] types = new int[operatorNumber][3]; 2296 2297 Iterator iterator = extendedOperands.iterator(); 2298 2299 Expression leftOperand= node.getLeftOperand(); 2300 Expression rightOperand= node.getRightOperand(); 2301 int leftTypeId; 2302 int rightTypeId; 2303 boolean unbox= char0 != '=' || leftOperand.resolveTypeBinding().isPrimitive() || rightOperand.resolveTypeBinding().isPrimitive(); 2305 if (unbox) { 2306 leftTypeId= getUnBoxedTypeId(leftOperand); 2307 rightTypeId = getUnBoxedTypeId(rightOperand); 2308 } else { 2309 leftTypeId= getTypeId(leftOperand); 2310 rightTypeId = getTypeId(rightOperand); 2311 } 2312 int resultTypeId = Instruction.getBinaryPromotionType(leftTypeId, rightTypeId); 2313 2314 types[0][0] = resultTypeId; 2315 types[0][1] = leftTypeId; 2316 types[0][2] = rightTypeId; 2317 2318 for (int i = 1; i < operatorNumber; i++) { 2319 Expression operand = (Expression) iterator.next(); 2320 leftTypeId = resultTypeId; 2321 rightTypeId = getUnBoxedTypeId(operand); 2322 resultTypeId = Instruction.getBinaryPromotionType(leftTypeId, rightTypeId); 2323 types[i][0] = resultTypeId; 2324 types[i][1] = leftTypeId; 2325 types[i][2] = rightTypeId; 2326 } 2327 2328 boolean unrecognized= false; 2329 2330 switch (char0) { 2331 case '*': for (int i = operatorNumber - 1; i >= 0; i--) { 2333 push(new MultiplyOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2334 } 2335 break; 2336 case '/': for (int i = operatorNumber - 1; i >= 0; i--) { 2338 push(new DivideOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2339 } 2340 break; 2341 case '%': for (int i = operatorNumber - 1; i >= 0; i--) { 2343 push(new RemainderOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2344 } 2345 break; 2346 case '+': for (int i = operatorNumber - 1; i >= 0; i--) { 2348 push(new PlusOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2349 } 2350 break; 2351 case '-': for (int i = operatorNumber - 1; i >= 0; i--) { 2353 push(new MinusOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2354 } 2355 break; 2356 case '<': switch (char1) { 2358 case '\0': for (int i = operatorNumber - 1; i >= 0; i--) { 2360 push(new LessOperator(types[i][1], types[i][2], fCounter)); 2361 } 2362 break; 2363 case '<': for (int i = operatorNumber - 1; i >= 0; i--) { 2365 push(new LeftShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter)); 2366 } 2367 break; 2368 case '=': for (int i = operatorNumber - 1; i >= 0; i--) { 2370 push(new LessEqualOperator(types[i][1], types[i][2], fCounter)); 2371 } 2372 break; 2373 default: 2374 unrecognized= true; 2375 break; 2376 } 2377 break; 2378 case '>': switch (char1) { 2380 case '\0': for (int i = operatorNumber - 1; i >= 0; i--) { 2382 push(new GreaterOperator(types[i][1], types[i][2], fCounter)); 2383 } 2384 break; 2385 case '>': switch (char2) { 2387 case '\0': for (int i = operatorNumber - 1; i >= 0; i--) { 2389 push(new RightShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter)); 2390 } 2391 break; 2392 case '>': for (int i = operatorNumber - 1; i >= 0; i--) { 2394 push(new UnsignedRightShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter)); 2395 } 2396 break; 2397 } 2398 break; 2399 case '=': for (int i = operatorNumber - 1; i >= 0; i--) { 2401 push(new GreaterEqualOperator(types[i][1], types[i][2], fCounter)); 2402 } 2403 break; 2404 default: 2405 unrecognized= true; 2406 break; 2407 } 2408 break; 2409 case '=': for (int i = operatorNumber - 1; i >= 0; i--) { 2411 push(new EqualEqualOperator(types[i][1], types[i][2], true, fCounter)); 2412 } 2413 break; 2414 case '!': for (int i = operatorNumber - 1; i >= 0; i--) { 2416 push(new EqualEqualOperator(types[i][1], types[i][2], false, fCounter)); 2417 } 2418 break; 2419 case '^': for (int i = operatorNumber - 1; i >= 0; i--) { 2421 push(new XorOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2422 } 2423 break; 2424 case '|': switch (char1) { 2426 case '\0': for (int i = operatorNumber - 1; i >= 0; i--) { 2428 push(new OrOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2429 } 2430 break; 2431 case '|': for (int i = operatorNumber - 1; i >= 0; i--) { 2433 push(new NoOp(fCounter)); 2434 } 2435 break; 2436 default: 2437 unrecognized= true; 2438 break; 2439 } 2440 break; 2441 case '&': switch (char1) { 2443 case '\0': for (int i = operatorNumber - 1; i >= 0; i--) { 2445 push(new AndOperator(types[i][0], types[i][1], types[i][2], fCounter)); 2446 } 2447 break; 2448 case '&': for (int i = operatorNumber - 1; i >= 0; i--) { 2450 push(new NoOp(fCounter)); 2451 } 2452 break; 2453 default: 2454 unrecognized= true; 2455 break; 2456 } 2457 break; 2458 default: 2459 unrecognized= true; 2460 break; 2461 } 2462 2463 if (unrecognized) { 2464 setHasError(true); 2465 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_infix_operator____13 + opToken); 2466 } 2467 2468 if (hasErrors()) { 2469 return true; 2470 } 2471 2472 iterator = extendedOperands.iterator(); 2473 2474 if ((char0 == '&' && char1 == '&') || (char0 == '|' && char1 == '|')) { 2476 boolean isOrOr= char0 == '|'; 2477 2478 ConditionalJump[] conditionalJumps= new ConditionalJump[operatorNumber]; 2479 int[] conditionalJumpAddresses = new int[operatorNumber]; 2480 2481 boolean storeRequired= unBoxing(leftOperand.resolveTypeBinding()); 2482 leftOperand.accept(this); 2483 if (storeRequired) { 2484 storeInstruction(); 2485 } 2486 2487 ConditionalJump conditionalJump= new ConditionalJump(isOrOr); 2488 conditionalJumps[0]= conditionalJump; 2489 conditionalJumpAddresses[0] = fCounter; 2490 push(conditionalJump); 2491 storeInstruction(); 2492 2493 storeRequired= unBoxing(rightOperand.resolveTypeBinding()); 2494 rightOperand.accept(this); 2495 if (storeRequired) { 2496 storeInstruction(); 2497 } 2498 2499 for (int i= 1; i < operatorNumber; i ++) { 2500 conditionalJump= new ConditionalJump(isOrOr); 2501 conditionalJumps[i]= conditionalJump; 2502 conditionalJumpAddresses[i] = fCounter; 2503 push(conditionalJump); 2504 storeInstruction(); 2505 Expression operand= (Expression) iterator.next(); 2506 storeRequired= unBoxing(operand.resolveTypeBinding()); 2507 operand.accept(this); 2508 if (storeRequired) { 2509 storeInstruction(); 2510 } 2511 } 2512 2513 Jump jump = new Jump(); 2514 jump.setOffset(1); 2515 push(jump); 2516 storeInstruction(); 2517 2518 for (int i= 0; i < operatorNumber; i ++) { 2519 conditionalJumps[i].setOffset(fCounter - conditionalJumpAddresses[i] - 1); 2520 } 2521 2522 push(new PushBoolean(isOrOr)); 2523 storeInstruction(); 2524 2525 storeInstruction(); 2527 2528 } else { 2530 boolean storeRequired= false; 2531 if (unbox) { 2532 storeRequired= unBoxing(leftOperand.resolveTypeBinding()); 2533 } 2534 leftOperand.accept(this); 2535 if (storeRequired) { 2536 storeInstruction(); 2537 } 2538 if (unbox) { 2539 storeRequired= unBoxing(rightOperand.resolveTypeBinding()); 2540 } 2541 rightOperand.accept(this); 2542 if (storeRequired) { 2543 storeInstruction(); 2544 } 2545 2546 storeInstruction(); 2547 for (int i= 1; i < operatorNumber; i ++) { 2548 Expression operand= (Expression) iterator.next(); 2549 if (unbox) { 2550 storeRequired= unBoxing(operand.resolveTypeBinding()); 2551 } 2552 operand.accept(this); 2553 if (storeRequired) { 2554 storeInstruction(); 2555 } 2556 storeInstruction(); 2557 } 2558 } 2559 2560 2561 2562 return false; 2563 } 2564 2565 2568 public boolean visit(Initializer node) { 2569 return true; 2570 } 2571 2572 2575 public boolean visit(InstanceofExpression node) { 2576 if (!isActive()) { 2577 return false; 2578 } 2579 push(new InstanceOfOperator(fCounter)); 2580 return true; 2581 } 2582 2583 2586 public boolean visit(Javadoc node) { 2587 return false; 2588 } 2589 2590 2594 public boolean visit(LabeledStatement node) { 2595 node.getBody().accept(this); 2596 return false; 2597 } 2598 2599 2602 public boolean visit(LineComment node) { 2603 return false; 2604 } 2605 2606 2607 2610 public boolean visit(MarkerAnnotation node) { 2611 return false; 2612 } 2613 2614 2617 public boolean visit(MemberRef node) { 2618 return false; 2619 } 2620 2621 2624 public boolean visit(MemberValuePair node) { 2625 return false; 2626 } 2627 2628 2631 public boolean visit(MethodDeclaration node) { 2632 int start= node.getStartPosition(); 2633 int end= start + node.getLength(); 2634 if (start < fStartPosition && end > fStartPosition) { 2635 return true; 2636 } 2637 return false; 2638 } 2639 2640 2645 public boolean visit(MethodInvocation node) { 2646 if (!isActive()) { 2647 return false; 2648 } 2649 2650 IMethodBinding methodBinding= (IMethodBinding) node.getName().resolveBinding(); 2651 if (methodBinding == null) { 2652 ASTNode root = node.getRoot(); 2654 if (root instanceof CompilationUnit) { 2655 CompilationUnit cu = (CompilationUnit) root; 2656 IProblem[] problems = cu.getProblems(); 2657 for (int i = 0; i < problems.length; i++) { 2658 IProblem problem = problems[i]; 2659 setHasError(true); 2660 addErrorMessage(problem.getMessage()); 2661 } 2662 } 2663 } 2664 2665 if (hasErrors()) { 2666 return true; 2667 } 2668 2669 if (containsALocalType(methodBinding)) { 2670 setHasError(true); 2671 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Method_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_32); 2672 } 2673 2674 if (hasErrors()) { 2675 return true; 2676 } 2677 2678 ITypeBinding[] parameterTypes = methodBinding.getParameterTypes(); 2679 int paramCount= parameterTypes.length; 2680 String selector= methodBinding.getName(); 2681 2682 String signature= getMethodSignature(methodBinding, null).replace('.','/'); 2683 2684 boolean isStatic= Flags.isStatic(methodBinding.getModifiers()); 2685 Expression expression= node.getExpression(); 2686 2687 if (isStatic) { 2688 String typeName= getTypeName(methodBinding.getDeclaringClass()); 2689 push(new SendStaticMessage(typeName, selector, signature, paramCount, fCounter)); 2690 if (expression != null) { 2691 node.getExpression().accept(this); 2692 addPopInstruction(); 2693 } 2694 } else { 2695 push(new SendMessage(selector, signature, paramCount, null, fCounter)); 2696 if (expression == null) { 2697 push(new PushThis(getEnclosingLevel(node, methodBinding.getDeclaringClass()))); 2698 storeInstruction(); 2699 } else { 2700 node.getExpression().accept(this); 2701 } 2702 } 2703 2704 List arguments = node.arguments(); 2705 int argCount = arguments.size(); 2706 if (methodBinding.isVarargs() && !(paramCount == argCount && parameterTypes[paramCount - 1].getDimensions() == ((Expression)arguments.get(argCount - 1)).resolveTypeBinding().getDimensions())) { 2707 Iterator iterator= arguments.iterator(); 2710 for (int i= 0; i < paramCount - 1; i++) { 2712 Expression argument= (Expression)iterator.next(); 2713 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i]); 2714 argument.accept(this); 2715 if (storeRequired) { 2716 storeInstruction(); 2717 } 2718 } 2719 ITypeBinding varargsParameterType= parameterTypes[paramCount - 1]; 2721 ITypeBinding varargsElementType= varargsParameterType.getElementType(); 2722 push(new ArrayInitializerInstruction(getTypeSignature(varargsElementType), argCount - paramCount + 1, varargsParameterType.getDimensions(), fCounter)); 2723 while (iterator.hasNext()) { 2724 Expression argument= (Expression) iterator.next(); 2725 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), varargsElementType); 2726 argument.accept(this); 2727 if (storeRequired) { 2728 storeInstruction(); 2729 } 2730 } 2731 storeInstruction(); 2732 } else { 2733 Iterator iterator= arguments.iterator(); 2734 int i= 0; 2735 while (iterator.hasNext()) { 2736 Expression argument= (Expression) iterator.next(); 2737 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i++]); 2738 argument.accept(this); 2739 if (storeRequired) { 2740 storeInstruction(); 2741 } 2742 } 2743 } 2744 2745 return false; 2746 } 2747 2748 2751 public boolean visit(MethodRef node) { 2752 return false; 2753 } 2754 2755 2758 public boolean visit(MethodRefParameter node) { 2759 return false; 2760 } 2761 2762 2765 public boolean visit(Modifier node) { 2766 return false; 2767 } 2768 2769 2772 public boolean visit(NormalAnnotation node) { 2773 return false; 2774 } 2775 2776 2779 public boolean visit(NullLiteral node) { 2780 if (!isActive()) { 2781 return false; 2782 } 2783 2784 push(new PushNull()); 2785 2786 return true; 2787 } 2788 2789 2792 public boolean visit(NumberLiteral node) { 2793 if (!isActive()) { 2794 return false; 2795 } 2796 2797 int literalType= getTypeId(node); 2798 String token= node.getToken(); 2799 int tokenLastCharOffset= token.length() - 1; 2800 char lastChar= token.charAt(tokenLastCharOffset); 2801 String subToken= token.substring(0, tokenLastCharOffset); 2802 2803 2804 switch (literalType) { 2805 case Instruction.T_int: 2806 push(new PushInt(parseIntValue(token))); 2807 break; 2808 case Instruction.T_long: 2809 push(new PushLong(parseLongValue(subToken))); 2810 break; 2811 case Instruction.T_float: 2812 push(new PushFloat(Float.parseFloat(subToken))); 2813 break; 2814 case Instruction.T_double: 2815 if (lastChar == 'D' || lastChar == 'd') { 2816 push(new PushDouble(Double.parseDouble(subToken))); 2817 } else { 2818 push(new PushDouble(Double.parseDouble(token))); 2819 } 2820 break; 2821 } 2822 2823 return true; 2824 } 2825 2826 2830 private int parseIntValue(String token) { 2831 int tokenLength= token.length(); 2832 if (tokenLength < 10) { 2833 return Integer.decode(token).intValue(); 2835 } 2836 switch (getBase(token)) { 2837 case 8: 2838 return (Integer.decode(token.substring(0, tokenLength - 1)).intValue() << 3) | Integer.decode("0" + token.charAt(tokenLength - 1)).intValue(); case 10: 2840 return Integer.decode(token).intValue(); 2841 case 16: 2842 return (Integer.decode(token.substring(0, tokenLength - 1)).intValue() << 4) | Integer.decode("0x" + token.charAt(tokenLength - 1)).intValue(); default: 2844 return 0; 2846 } 2847 } 2848 2849 2850 2854 private long parseLongValue(String token) { 2855 int tokenLength= token.length(); 2856 if (tokenLength < 18) { 2857 return Long.decode(token).longValue(); 2859 } 2860 switch (getBase(token)) { 2861 case 8: 2862 return (Long.decode(token.substring(0, tokenLength - 1)).longValue() << 3) | Long.decode("0" + token.charAt(tokenLength - 1)).longValue(); case 10: 2864 return Long.decode(token).longValue(); 2865 case 16: 2866 return (Long.decode(token.substring(0, tokenLength - 1)).longValue() << 4) | Long.decode("0x" + token.charAt(tokenLength - 1)).longValue(); default: 2868 return 0; 2870 } 2871 } 2872 2873 2878 private int getBase(String token) { 2879 if (token.charAt(0) == '0') { 2880 if (token.charAt(1) == 'x') { 2881 return 16; } 2883 return 8; } 2885 return 10; } 2887 2888 2891 public boolean visit(PackageDeclaration node) { 2892 return false; 2893 } 2894 2895 2898 public boolean visit(ParameterizedType node) { 2899 if (!isActive()) { 2900 return false; 2901 } 2902 ITypeBinding typeBinding = node.resolveBinding(); 2903 push(new PushType(getTypeName(typeBinding))); 2904 return false; 2905 } 2906 2907 2910 public boolean visit(ParenthesizedExpression node) { 2911 if (!isActive()) { 2912 return false; 2913 } 2914 return true; 2915 } 2916 2917 2920 public boolean visit(PostfixExpression node) { 2921 if (!isActive()) { 2922 return false; 2923 } 2924 2925 Expression operand= node.getOperand(); 2926 int expressionTypeId = getTypeId(operand); 2927 2928 String opToken = node.getOperator().toString(); 2929 char char0 = opToken.charAt(0); 2930 2931 if (expressionTypeId == Instruction.T_Object) { 2932 2933 int expressionUnBoxedTypeId= getUnBoxedTypeId(operand); 2934 2935 AssignmentOperator assignmentInstruction= new AssignmentOperator(Instruction.T_Object, Instruction.T_Object, fCounter); 2936 push(assignmentInstruction); 2937 operand.accept(this); 2938 switch (char0) { 2939 case '+': push(new PlusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter)); 2941 break; 2942 case '-': push(new MinusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter)); 2944 break; 2945 default: 2946 setHasError(true); 2947 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_postfix_operator____15 + opToken); 2948 break; 2949 } 2950 push(new Value(fCounter)); 2951 push(new Dup()); 2952 storeInstruction(); storeInstruction(); push(new DupX1()); 2955 storeInstruction(); unBoxing(operand.resolveTypeBinding()); 2957 storeInstruction(); push(new PushInt(1)); 2959 storeInstruction(); storeInstruction(); boxing(operand.resolveTypeBinding(), null); 2962 storeInstruction(); storeInstruction(); push(new Pop(assignmentInstruction.getSize() + 1)); 2965 2966 2967 return false; 2968 } 2969 2970 switch (char0) { 2971 case '+': push(new PostfixPlusPlusOperator(expressionTypeId, fCounter)); 2973 break; 2974 case '-': push(new PostfixMinusMinusOperator(expressionTypeId, fCounter)); 2976 break; 2977 default: 2978 setHasError(true); 2979 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_postfix_operator____15 + opToken); 2980 break; 2981 } 2982 2983 return true; 2984 } 2985 2986 2989 public boolean visit(PrefixExpression node) { 2990 if (!isActive()) { 2991 return false; 2992 } 2993 2994 Expression operand= node.getOperand(); 2995 int expressionTypeId = getTypeId(operand); 2996 2997 String opToken = node.getOperator().toString(); 2998 int opTokenLength = opToken.length(); 2999 char char0 = opToken.charAt(0); 3000 char char1 = '\0'; 3001 if (opTokenLength > 1) { 3002 char1 = opToken.charAt(1); 3003 } 3004 3005 boolean unrecognized = false; 3006 3007 if (expressionTypeId == Instruction.T_Object) { 3008 3009 int expressionUnBoxedTypeId= getUnBoxedTypeId(operand); 3010 3011 if (char1 == '\0') { 3012 switch (char0) { 3013 case '+': push(new UnaryPlusOperator(expressionUnBoxedTypeId, fCounter)); 3015 break; 3016 case '-': push(new UnaryMinusOperator(expressionUnBoxedTypeId, fCounter)); 3018 break; 3019 case '~': push(new TwiddleOperator(expressionUnBoxedTypeId, fCounter)); 3021 break; 3022 case '!': push(new NotOperator(expressionUnBoxedTypeId, fCounter)); 3024 break; 3025 default: 3026 setHasError(true); 3027 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 3028 break; 3029 } 3030 3031 unBoxing(operand.resolveTypeBinding()); 3032 operand.accept(this); 3033 storeInstruction(); 3035 } else { 3036 3038 push(new AssignmentOperator(Instruction.T_Object, Instruction.T_Object, fCounter)); 3039 3040 operand.accept(this); 3041 3042 boxing(operand.resolveTypeBinding(), null); 3043 3044 switch (char1) { 3045 case '+': 3046 push(new PlusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter)); 3047 break; 3048 case '-': 3049 push(new MinusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter)); 3050 break; 3051 default: 3052 setHasError(true); 3053 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 3054 break; 3055 } 3056 3057 unBoxing(operand.resolveTypeBinding()); 3058 push(new Dup()); 3059 storeInstruction(); storeInstruction(); push(new PushInt(1)); 3062 storeInstruction(); 3064 storeInstruction(); storeInstruction(); 3067 } 3068 3069 return false; 3070 } 3071 3072 switch (char0) { 3073 case '+': switch (char1) { 3075 case '\0': push(new UnaryPlusOperator(expressionTypeId, fCounter)); 3077 break; 3078 case '+': push(new PrefixPlusPlusOperator(expressionTypeId, fCounter)); 3080 break; 3081 default: 3082 unrecognized= true; 3083 break; 3084 } 3085 break; 3086 case '-': switch (char1) { 3088 case '\0': push(new UnaryMinusOperator(expressionTypeId, fCounter)); 3090 break; 3091 case '-': push(new PrefixMinusMinusOperator(expressionTypeId, fCounter)); 3093 break; 3094 default: 3095 unrecognized= true; 3096 break; 3097 } 3098 break; 3099 case '~': push(new TwiddleOperator(expressionTypeId, fCounter)); 3101 break; 3102 case '!': push(new NotOperator(expressionTypeId, fCounter)); 3104 break; 3105 default: 3106 unrecognized= true; 3107 break; 3108 } 3109 3110 3111 if (unrecognized) { 3112 setHasError(true); 3113 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 3114 } 3115 3116 return true; 3117 } 3118 3119 3122 public boolean visit(PrimitiveType node) { 3123 if (!isActive()) { 3124 return false; 3125 } 3126 3127 return true; 3128 } 3129 3130 3133 public boolean visit(QualifiedName node) { 3134 if (!isActive()) { 3135 return false; 3136 } 3137 3138 if (hasErrors()) { 3139 return true; 3140 } 3141 3142 IBinding binding = node.resolveBinding(); 3143 switch (binding.getKind()) { 3144 case IBinding.TYPE: 3145 node.getName().accept(this); 3146 break; 3147 case IBinding.VARIABLE: 3148 SimpleName fieldName= node.getName(); 3149 IVariableBinding fieldBinding= (IVariableBinding) fieldName.resolveBinding(); 3150 ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass(); 3151 String fieldId = fieldName.getIdentifier(); 3152 3153 if (Modifier.isStatic(fieldBinding.getModifiers())) { 3154 push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter)); 3155 } else { 3156 if (declaringTypeBinding == null) { 3157 push(new PushArrayLength(fCounter)); 3158 } else { 3159 push(new PushFieldVariable(fieldId, getTypeSignature(declaringTypeBinding), fCounter)); 3160 } 3161 node.getQualifier().accept(this); 3162 } 3163 storeInstruction(); 3164 break; 3165 } 3166 3167 return false; 3168 } 3169 3170 3173 public boolean visit(QualifiedType node) { 3174 if (!isActive()) { 3175 return false; 3176 } 3177 ITypeBinding typeBinding = node.resolveBinding(); 3178 push(new PushType(getTypeName(typeBinding))); 3179 return false; 3180 } 3181 3182 3185 public boolean visit(ReturnStatement node) { 3186 if (!isActive()) { 3187 return false; 3188 } 3189 push(new ReturnInstruction(fCounter)); 3190 return true; 3191 } 3192 3193 3196 public boolean visit(SimpleName node) { 3197 if (!isActive()) { 3198 return false; 3199 } 3200 3201 if (hasErrors()) { 3202 return true; 3203 } 3204 3205 IBinding binding = node.resolveBinding(); 3206 3207 String variableId = node.getIdentifier(); 3208 if (binding == null) { 3209 setHasError(true); 3210 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_binding_null_for__17 + variableId); 3211 return true; 3212 } 3213 3214 switch (binding.getKind()) { 3215 case IBinding.TYPE: 3216 ITypeBinding typeBinding= (ITypeBinding) binding; 3217 push(new PushType(getTypeName(typeBinding))); 3218 break; 3219 case IBinding.VARIABLE: 3220 IVariableBinding variableBinding= (IVariableBinding) binding; 3221 ITypeBinding declaringTypeBinding= variableBinding.getDeclaringClass(); 3222 if (variableBinding.isField()) { 3223 if (Modifier.isStatic(variableBinding.getModifiers())) { 3224 push(new PushStaticFieldVariable(variableId, getTypeName(declaringTypeBinding), fCounter)); 3225 } else { 3226 if (isALocalType(declaringTypeBinding)) { 3227 setHasError(true); 3228 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_36); 3229 return false; 3230 } 3231 push(new PushFieldVariable(variableId, getTypeSignature(declaringTypeBinding), fCounter)); 3232 push(new PushThis(getEnclosingLevel(node, declaringTypeBinding))); 3233 storeInstruction(); 3234 } 3235 } else { 3236 push(new PushLocalVariable(variableId)); 3237 } 3238 break; 3239 } 3240 return true; 3241 } 3242 3243 3248 public boolean visit(SimpleType node) { 3249 if (!isActive()) { 3250 return false; 3251 } 3252 3253 ITypeBinding typeBinding = node.resolveBinding(); 3254 push(new PushType(getTypeName(typeBinding))); 3255 3256 return false; 3257 } 3258 3259 3262 public boolean visit(SingleMemberAnnotation node) { 3263 return false; 3264 } 3265 3266 3270 public boolean visit(SingleVariableDeclaration node) { 3271 if (!isActive()) { 3272 return false; 3273 } 3274 3275 Expression initializer= node.getInitializer(); 3276 boolean hasInitializer= initializer != null; 3277 3278 ITypeBinding typeBinding= node.getType().resolveBinding(); 3279 int typeDimension= typeBinding.getDimensions(); 3280 if (typeDimension != 0) { 3281 typeBinding= typeBinding.getElementType(); 3282 } 3283 3284 push(new LocalVariableCreation(node.getName().getIdentifier(), getTypeSignature(typeBinding), typeDimension, typeBinding.isPrimitive(), hasInitializer, fCounter)); 3285 if (hasInitializer) { 3286 initializer.accept(this); 3287 } 3288 3289 return false; 3290 } 3291 3292 3295 public boolean visit(StringLiteral node) { 3296 if (!isActive()) { 3297 return false; 3298 } 3299 3300 push(new PushString(node.getLiteralValue())); 3301 3302 return true; 3303 } 3304 3305 3308 public boolean visit(SuperConstructorInvocation node) { 3309 if (!isActive()) { 3310 return false; 3311 } 3312 setHasError(true); 3313 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_super_constructor_invocation_cannot_be_used_in_an_evaluation_expression_19); 3314 return false; 3315 } 3316 3317 3320 public boolean visit(SuperFieldAccess node) { 3321 if (!isActive()) { 3322 return false; 3323 } 3324 3325 SimpleName fieldName= node.getName(); 3326 IVariableBinding fieldBinding= (IVariableBinding) fieldName.resolveBinding(); 3327 ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass(); 3328 String fieldId = fieldName.getIdentifier(); 3329 3330 if (Modifier.isStatic(fieldBinding.getModifiers())) { 3331 push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter)); 3332 } else { 3333 Name qualifier = node.getQualifier(); 3334 int superLevel= 1; 3335 int enclosingLevel= 0; 3336 if (qualifier != null) { 3337 superLevel= getSuperLevel(qualifier.resolveTypeBinding(), declaringTypeBinding); 3338 enclosingLevel= getEnclosingLevel(node, (ITypeBinding)qualifier.resolveBinding()); 3339 } 3340 push(new PushFieldVariable(fieldId, superLevel, fCounter)); 3341 push(new PushThis(enclosingLevel)); 3342 storeInstruction(); 3343 } 3344 3345 return false; 3346 } 3347 3348 3353 public boolean visit(SuperMethodInvocation node) { 3354 if (!isActive()) { 3355 return false; 3356 } 3357 3358 IMethodBinding methodBinding = (IMethodBinding) node.getName().resolveBinding(); 3359 3360 if (containsALocalType(methodBinding)) { 3361 setHasError(true); 3362 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Method_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_32); 3363 } 3364 3365 if (hasErrors()) { 3366 return true; 3367 } 3368 3369 ITypeBinding[] parameterTypes = methodBinding.getParameterTypes(); 3370 int paramCount = parameterTypes.length; 3371 String selector = methodBinding.getName(); 3372 String signature = getMethodSignature(methodBinding, null); 3373 3374 Name qualifier= node.getQualifier(); 3375 if (Modifier.isStatic(methodBinding.getModifiers())) { 3376 push(new SendStaticMessage(getTypeName(methodBinding.getDeclaringClass()), selector, signature, paramCount, fCounter)); 3377 } else { 3378 push(new SendMessage(selector, signature, paramCount, getTypeSignature(methodBinding.getDeclaringClass()), fCounter)); 3379 int enclosingLevel= 0; 3380 if (qualifier != null) { 3381 enclosingLevel= getEnclosingLevel(node, (ITypeBinding)qualifier.resolveBinding()); 3382 } 3383 push(new PushThis(enclosingLevel)); 3384 storeInstruction(); 3385 } 3386 3387 List arguments = node.arguments(); 3388 int argCount = arguments.size(); 3389 if (methodBinding.isVarargs() && !(paramCount == argCount && parameterTypes[paramCount - 1].getDimensions() == ((Expression)arguments.get(argCount - 1)).resolveTypeBinding().getDimensions())) { 3390 Iterator iterator= arguments.iterator(); 3393 for (int i= 0; i < paramCount - 1; i++) { 3395 Expression argument= (Expression) iterator.next(); 3396 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i]); 3397 argument.accept(this); 3398 if (storeRequired) { 3399 storeInstruction(); 3400 } 3401 } 3402 ITypeBinding varargsParameterType= parameterTypes[paramCount - 1]; 3404 ITypeBinding varargsElementType= varargsParameterType.getElementType(); 3405 push(new ArrayInitializerInstruction(getTypeSignature(varargsElementType), argCount - paramCount + 1, varargsParameterType.getDimensions(), fCounter)); 3406 while (iterator.hasNext()) { 3407 Expression argument= (Expression) iterator.next(); 3408 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), varargsElementType); 3409 argument.accept(this); 3410 if (storeRequired) { 3411 storeInstruction(); 3412 } 3413 } 3414 storeInstruction(); 3415 } else { 3416 Iterator iterator= arguments.iterator(); 3417 int i= 0; 3418 while (iterator.hasNext()) { 3419 Expression argument= (Expression) iterator.next(); 3420 boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i++]); 3421 argument.accept(this); 3422 if (storeRequired) { 3423 storeInstruction(); 3424 } 3425 } 3426 } 3427 3428 return false; 3429 } 3430 3431 3434 public boolean visit(SwitchCase node) { 3435 return false; 3437 } 3438 3439 3442 public boolean visit(SwitchStatement node) { 3443 if (!isActive()) { 3444 return false; 3445 } 3446 push(new NoOp(fCounter)); 3447 int switchStart= fCounter; 3448 node.getExpression().accept(this); 3449 3450 ArrayList statementsDefault= null; 3451 Jump jumpDefault= null; 3452 ArrayList jumpsStatements= new ArrayList (); 3453 ArrayList [] currentJumpsStatements= new ArrayList [] {new ArrayList (), null}; 3454 jumpsStatements.add(currentJumpsStatements); 3455 3456 for (Iterator iter= node.statements().iterator(); iter.hasNext();) { 3457 Statement statement= (Statement) iter.next(); 3458 if (statement instanceof SwitchCase) { 3459 SwitchCase switchCase= (SwitchCase) statement; 3460 if (switchCase.isDefault()) { 3461 jumpDefault= new Jump(); 3462 push(jumpDefault); 3463 storeInstruction(); statementsDefault= new ArrayList (); 3465 } else { 3466 push(new EqualEqualOperator(Instruction.T_int, Instruction.T_int, true, fCounter)); 3467 push(new Dup()); 3468 storeInstruction(); switchCase.getExpression().accept(this); 3470 storeInstruction(); ConditionalJump condJump= new ConditionalJump(true); 3472 push(condJump); 3473 storeInstruction(); if (currentJumpsStatements[1] != null) { 3475 currentJumpsStatements= new ArrayList [] {new ArrayList (), null}; 3476 jumpsStatements.add(currentJumpsStatements); 3477 } 3478 currentJumpsStatements[0].add(condJump); 3479 } 3480 } else { 3481 if (statementsDefault != null) { 3482 statementsDefault.add(statement); 3483 } else { 3484 if (currentJumpsStatements[1] == null) { 3485 currentJumpsStatements[1]= new ArrayList (); 3486 } 3487 currentJumpsStatements[1].add(statement); 3488 } 3489 } 3490 } 3491 3492 Jump jumpEnd= null; 3493 if (jumpDefault == null) { 3494 push(new Pop(0)); 3495 storeInstruction(); jumpEnd= new Jump(); 3497 push(jumpEnd); 3498 storeInstruction(); } 3500 3501 for (Iterator iter= jumpsStatements.iterator(); iter.hasNext();) { 3502 currentJumpsStatements= (ArrayList []) iter.next(); 3503 for (Iterator iterator= currentJumpsStatements[0].iterator(); iterator.hasNext();) { 3504 ConditionalJump condJump= (ConditionalJump) iterator.next(); 3505 condJump.setOffset((fCounter - fInstructions.indexOf(condJump)) - 1); 3506 } 3507 if (currentJumpsStatements[1] != null) { 3508 push(new Pop(0)); 3509 storeInstruction(); for (Iterator iterator= currentJumpsStatements[1].iterator(); iterator.hasNext();) { 3511 ((Statement) iterator.next()).accept(this); 3512 } 3513 } 3514 } 3515 3516 if (jumpDefault != null) { 3518 jumpDefault.setOffset((fCounter - fInstructions.indexOf(jumpDefault)) - 1); 3519 push(new Pop(0)); 3520 storeInstruction(); for (Iterator iterator= statementsDefault.iterator(); iterator.hasNext();) { 3522 ((Statement) iterator.next()).accept(this); 3523 } 3524 } else { 3525 jumpEnd.setOffset((fCounter - fInstructions.indexOf(jumpEnd)) - 1); 3526 } 3527 3528 String label= getLabel(node); 3531 for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) { 3532 CompleteInstruction instruction= (CompleteInstruction) iter.next(); 3533 Jump jumpInstruction= instruction.fInstruction; 3534 int instructionAddress= fInstructions.indexOf(jumpInstruction); 3535 if (instructionAddress > switchStart && (instruction.fLabel == null || instruction.fLabel.equals(label))) { 3536 iter.remove(); 3537 if (instruction.fIsBreak) { 3538 jumpInstruction.setOffset((fCounter - instructionAddress) - 1); 3540 } 3541 } 3542 } 3543 3544 return false; 3545 } 3546 3547 3550 public boolean visit(SynchronizedStatement node) { 3551 if (!isActive()) { 3552 return false; 3553 } 3554 return true; 3555 } 3556 3557 3560 public boolean visit(TagElement node) { 3561 return false; 3562 } 3563 3564 3567 public boolean visit(TextElement node) { 3568 return false; 3569 } 3570 3571 3574 public boolean visit(ThisExpression node) { 3575 if (!isActive()) { 3576 return false; 3577 } 3578 3579 Name qualifier= node.getQualifier(); 3580 int enclosingLevel= 0; 3581 if (qualifier != null) { 3582 enclosingLevel= getEnclosingLevel(node, (ITypeBinding)qualifier.resolveBinding()); 3583 } 3584 push(new PushThis(enclosingLevel)); 3585 3586 return false; 3587 } 3588 3589 3592 public boolean visit(ThrowStatement node) { 3593 if (!isActive()) { 3594 return false; 3595 } 3596 push(new ThrowInstruction(fCounter)); 3597 return true; 3598 } 3599 3600 3603 public boolean visit(TryStatement node) { 3604 if (!isActive()) { 3605 return false; 3606 } 3607 setHasError(true); 3608 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Try_statement_cannot_be_used_in_an_evaluation_expression_23); 3609 return true; 3610 } 3611 3612 3615 public boolean visit(TypeDeclaration node) { 3616 if (!isActive()) { 3617 return true; 3618 } 3619 setHasError(true); 3620 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Type_declaration_cannot_be_used_in_an_evaluation_expression_24); 3621 return false; 3622 } 3623 3624 3627 public boolean visit(TypeDeclarationStatement node) { 3628 if (!isActive()) { 3629 return true; 3630 } 3631 setHasError(true); 3632 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Type_declaration_statement_cannot_be_used_in_an_evaluation_expression_25); 3633 return false; 3634 } 3635 3636 3639 public boolean visit(TypeParameter node) { 3640 return false; 3641 } 3642 3643 3646 public boolean visit(TypeLiteral node) { 3647 if (!isActive()) { 3648 return false; 3649 } 3650 3651 push(new PushClassLiteralValue(fCounter)); 3652 3653 return true; 3654 } 3655 3656 3659 public boolean visit(VariableDeclarationExpression node) { 3660 3665 if (!isActive()) { 3666 return true; 3667 } 3668 for (Iterator iter= node.fragments().iterator(); iter.hasNext();) { 3669 ((VariableDeclarationFragment) iter.next()).accept(this); 3670 } 3671 return false; 3672 } 3673 3674 3677 public boolean visit(VariableDeclarationFragment node) { 3678 3683 if (!isActive()) { 3684 return true; 3685 } 3686 ITypeBinding varTypeBinding; 3688 ASTNode parent= node.getParent(); 3689 switch (parent.getNodeType()) { 3690 case ASTNode.VARIABLE_DECLARATION_EXPRESSION: 3691 varTypeBinding= ((VariableDeclarationExpression)parent).getType().resolveBinding(); 3692 break; 3693 case ASTNode.VARIABLE_DECLARATION_STATEMENT: 3694 varTypeBinding= ((VariableDeclarationStatement)parent).getType().resolveBinding(); 3695 break; 3696 default: 3697 setHasError(true); 3698 addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Error_in_type_declaration_statement); 3699 return false; 3700 } 3701 int typeDimension= varTypeBinding.getDimensions(); 3702 ITypeBinding elementBinding = varTypeBinding; 3703 if (typeDimension != 0) { 3704 elementBinding= elementBinding.getElementType(); 3705 } 3706 3707 Expression initializer= node.getInitializer(); 3708 boolean hasInitializer= initializer != null; 3709 3710 push(new LocalVariableCreation(node.getName().getIdentifier(), getTypeSignature(elementBinding), typeDimension, elementBinding.isPrimitive(), hasInitializer, fCounter)); 3711 3712 if (hasInitializer) { 3713 initializer.accept(this); 3714 ITypeBinding expBindnig = initializer.resolveTypeBinding(); 3715 if (expBindnig != null) { 3716 if (checkAutoBoxing(expBindnig, varTypeBinding)) { 3717 storeInstruction(); 3718 } 3719 } 3720 } 3721 3722 return false; 3723 } 3724 3725 3728 public boolean visit(VariableDeclarationStatement node) { 3729 3734 if (!isActive()) { 3735 return true; 3736 } 3737 for (Iterator iter= node.fragments().iterator(); iter.hasNext();) { 3738 ((VariableDeclarationFragment) iter.next()).accept(this); 3739 } 3740 return false; 3741 } 3742 3743 3746 public boolean visit(WildcardType node) { 3747 return false; 3749 } 3750 3751 3754 public boolean visit(WhileStatement node) { 3755 if (!isActive()) { 3756 return false; 3757 } 3758 3759 push(new NoOp(fCounter)); 3760 return true; 3761 } 3762 3763 3765 private int getTypeId(Expression expression) { 3766 ITypeBinding typeBinding = expression.resolveTypeBinding(); 3767 String typeName = typeBinding.getQualifiedName(); 3768 if (typeBinding.isPrimitive()) { 3769 return getPrimitiveTypeId(typeName); 3770 } else if ("java.lang.String".equals(typeName)){ return Instruction.T_String; 3772 } else { 3773 return Instruction.T_Object; 3774 } 3775 } 3776 3777 private int getUnBoxedTypeId(Expression expression) { 3778 ITypeBinding typeBinding = expression.resolveTypeBinding(); 3779 String typeName = typeBinding.getQualifiedName(); 3780 if (typeBinding.isPrimitive()) { 3781 return getPrimitiveTypeId(typeName); 3782 } else if ("java.lang.String".equals(typeName)){ return Instruction.T_String; 3784 } else { 3785 if ("java.lang.Integer".equals(typeName)) { return Instruction.T_int; 3788 } else if ("java.lang.Character".equals(typeName)) { return Instruction.T_char; 3790 } else if ("java.lang.Byte".equals(typeName)) { return Instruction.T_byte; 3792 } else if ("java.lang.Short".equals(typeName)) { return Instruction.T_short; 3794 } else if ("java.lang.Long".equals(typeName)) { return Instruction.T_long; 3796 } else if ("java.lang.Float".equals(typeName)) { return Instruction.T_float; 3798 } else if ("java.lang.Double".equals(typeName)) { return Instruction.T_double; 3800 } else if ("java.lang.Boolean".equals(typeName)) { return Instruction.T_boolean; 3802 } 3803 return Instruction.T_Object; 3804 } 3805 } 3806 3807 private int getTypeId(Type type) { 3808 if (type.isPrimitiveType()) { 3809 return getPrimitiveTypeId(((PrimitiveType)type).getPrimitiveTypeCode().toString()); 3810 } else if (type.isSimpleType()) { 3811 SimpleType simpleType = (SimpleType) type; 3812 if ("java.lang.String".equals(simpleType.getName())){ return Instruction.T_String; 3814 } 3815 return Instruction.T_Object; 3816 } else if (type.isArrayType()) { 3817 return Instruction.T_Object; 3818 } else { 3819 return Instruction.T_undefined; 3820 } 3821 3822 } 3823 3824 private String getMethodSignature(IMethodBinding methodBinding, String enclosingTypeSignature) { 3825 methodBinding= methodBinding.getMethodDeclaration(); 3826 ITypeBinding[] parameterTypes = methodBinding.getParameterTypes(); 3827 int i; 3828 int argCount; 3829 String [] parameterSignatures; 3830 if (enclosingTypeSignature == null) { 3831 i= 0; 3832 argCount= parameterTypes.length; 3833 parameterSignatures= new String [argCount]; 3834 } else { 3835 i= 1; 3836 argCount= parameterTypes.length + 1; 3837 parameterSignatures= new String [argCount]; 3838 parameterSignatures[0]= enclosingTypeSignature; 3839 } 3840 for (; i < argCount; i++) { 3841 parameterSignatures[i]= getTypeSignature(parameterTypes[i]); 3842 } 3843 String signature= Signature.createMethodSignature(parameterSignatures, getTypeSignature(methodBinding.getReturnType())); 3844 return signature; 3845 } 3846 3847 private int getPrimitiveTypeId(String typeName) { 3848 switch (typeName.charAt(0)) { 3849 case 'b': switch (typeName.charAt(1)) { 3851 case 'o': return Instruction.T_boolean; 3853 case 'y': return Instruction.T_byte; 3855 } 3856 break; 3857 case 'c': return Instruction.T_char; 3859 case 'd': return Instruction.T_double; 3861 case 'f': return Instruction.T_float; 3863 case 'i': return Instruction.T_int; 3865 case 'l': return Instruction.T_long; 3867 case 'n': 3868 return Instruction.T_null; 3869 case 's': return Instruction.T_short; 3871 case 'v': return Instruction.T_void; 3873 } 3874 return Instruction.T_undefined; 3875 } 3876} 3877 | Popular Tags |