1 11 package org.eclipse.jdt.internal.debug.eval.ast.engine; 12 13 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.jdt.core.Flags; 20 import org.eclipse.jdt.core.Signature; 21 import org.eclipse.jdt.core.dom.ASTNode; 22 import org.eclipse.jdt.core.dom.ASTVisitor; 23 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 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.BodyDeclaration; 36 import org.eclipse.jdt.core.dom.BooleanLiteral; 37 import org.eclipse.jdt.core.dom.BreakStatement; 38 import org.eclipse.jdt.core.dom.CastExpression; 39 import org.eclipse.jdt.core.dom.CatchClause; 40 import org.eclipse.jdt.core.dom.CharacterLiteral; 41 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 42 import org.eclipse.jdt.core.dom.CompilationUnit; 43 import org.eclipse.jdt.core.dom.ConditionalExpression; 44 import org.eclipse.jdt.core.dom.ConstructorInvocation; 45 import org.eclipse.jdt.core.dom.ContinueStatement; 46 import org.eclipse.jdt.core.dom.DoStatement; 47 import org.eclipse.jdt.core.dom.EmptyStatement; 48 import org.eclipse.jdt.core.dom.EnhancedForStatement; 49 import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 50 import org.eclipse.jdt.core.dom.EnumDeclaration; 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.IfStatement; 56 import org.eclipse.jdt.core.dom.ImportDeclaration; 57 import org.eclipse.jdt.core.dom.InfixExpression; 58 import org.eclipse.jdt.core.dom.Initializer; 59 import org.eclipse.jdt.core.dom.InstanceofExpression; 60 import org.eclipse.jdt.core.dom.Javadoc; 61 import org.eclipse.jdt.core.dom.LabeledStatement; 62 import org.eclipse.jdt.core.dom.LineComment; 63 import org.eclipse.jdt.core.dom.MarkerAnnotation; 64 import org.eclipse.jdt.core.dom.MemberRef; 65 import org.eclipse.jdt.core.dom.MemberValuePair; 66 import org.eclipse.jdt.core.dom.MethodDeclaration; 67 import org.eclipse.jdt.core.dom.MethodInvocation; 68 import org.eclipse.jdt.core.dom.MethodRef; 69 import org.eclipse.jdt.core.dom.MethodRefParameter; 70 import org.eclipse.jdt.core.dom.Modifier; 71 import org.eclipse.jdt.core.dom.Name; 72 import org.eclipse.jdt.core.dom.NormalAnnotation; 73 import org.eclipse.jdt.core.dom.NullLiteral; 74 import org.eclipse.jdt.core.dom.NumberLiteral; 75 import org.eclipse.jdt.core.dom.PackageDeclaration; 76 import org.eclipse.jdt.core.dom.ParameterizedType; 77 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 78 import org.eclipse.jdt.core.dom.PostfixExpression; 79 import org.eclipse.jdt.core.dom.PrefixExpression; 80 import org.eclipse.jdt.core.dom.PrimitiveType; 81 import org.eclipse.jdt.core.dom.QualifiedName; 82 import org.eclipse.jdt.core.dom.QualifiedType; 83 import org.eclipse.jdt.core.dom.ReturnStatement; 84 import org.eclipse.jdt.core.dom.SimpleName; 85 import org.eclipse.jdt.core.dom.SimpleType; 86 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 87 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 88 import org.eclipse.jdt.core.dom.StringLiteral; 89 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 90 import org.eclipse.jdt.core.dom.SuperFieldAccess; 91 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 92 import org.eclipse.jdt.core.dom.SwitchCase; 93 import org.eclipse.jdt.core.dom.SwitchStatement; 94 import org.eclipse.jdt.core.dom.SynchronizedStatement; 95 import org.eclipse.jdt.core.dom.TagElement; 96 import org.eclipse.jdt.core.dom.TextElement; 97 import org.eclipse.jdt.core.dom.ThisExpression; 98 import org.eclipse.jdt.core.dom.ThrowStatement; 99 import org.eclipse.jdt.core.dom.TryStatement; 100 import org.eclipse.jdt.core.dom.Type; 101 import org.eclipse.jdt.core.dom.TypeDeclaration; 102 import org.eclipse.jdt.core.dom.TypeDeclarationStatement; 103 import org.eclipse.jdt.core.dom.TypeLiteral; 104 import org.eclipse.jdt.core.dom.TypeParameter; 105 import org.eclipse.jdt.core.dom.VariableDeclarationExpression; 106 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 107 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 108 import org.eclipse.jdt.core.dom.WhileStatement; 109 import org.eclipse.jdt.core.dom.WildcardType; 110 111 112 public class SourceBasedSourceGenerator extends ASTVisitor { 113 114 private static final String RUN_METHOD_NAME= "___run"; private static final String EVAL_METHOD_NAME= "___eval"; private static final String EVAL_FIELD_NAME= "___field"; 118 private String [] fLocalVariableTypeNames; 119 private String [] fLocalVariableNames; 120 private String fCodeSnippet; 121 122 private boolean fRightTypeFound; 123 124 private boolean fCreateInAStaticMethod; 125 126 private boolean fEvaluateNextEndTypeDeclaration; 127 128 private String fError; 129 130 private CompilationUnit fUnit; 131 132 private String fTypeName; 133 134 private int fPosition; 135 136 private StringBuffer fSource; 137 138 private String fLastTypeName; 139 140 private String fCompilationUnitName; 141 142 private int fSnippetStartPosition; 143 private int fRunMethodStartOffset; 144 private int fRunMethodLength; 145 146 150 private int fSourceMajorLevel; 151 private int fSourceMinorLevel; 152 153 private Set fTypeParameters = new HashSet (); 154 155 160 public SourceBasedSourceGenerator(CompilationUnit unit, String typeName, int position, boolean createInAStaticMethod, String [] localTypesNames, String [] localVariables, String codeSnippet, String sourceLevel) { 161 fRightTypeFound= false; 162 fUnit= unit; 163 fTypeName= typeName; 164 fPosition= position; 165 fLocalVariableTypeNames= localTypesNames; 166 fLocalVariableNames= localVariables; 167 fCodeSnippet= codeSnippet; 168 fCreateInAStaticMethod= createInAStaticMethod; 169 int index = sourceLevel.indexOf('.'); 170 String num = sourceLevel.substring(0, index); 171 fSourceMajorLevel = Integer.valueOf(num).intValue(); 172 num = sourceLevel.substring(index + 1); 173 fSourceMinorLevel = Integer.valueOf(num).intValue(); 174 } 175 176 179 public String getSource() { 180 if (fSource == null) { 181 return null; 182 } 183 return fSource.toString(); 184 } 185 186 private CompilationUnit getCompilationUnit() { 187 return fUnit; 188 } 189 190 public String getCompilationUnitName() { 191 return fCompilationUnitName; 192 } 193 194 public int getSnippetStart() { 195 return fSnippetStartPosition; 196 } 197 public int getRunMethodStart() { 198 return fSnippetStartPosition - fRunMethodStartOffset; 199 } 200 public int getRunMethodLength() { 201 return fRunMethodLength; 202 } 203 204 private int getPosition() { 205 return fPosition; 206 } 207 208 private int getCorrespondingLineNumber(int charOffset) { 209 int lineNumber = getCompilationUnit().getLineNumber(charOffset); 210 return lineNumber < 1 ? 1 : lineNumber; 211 } 212 213 private boolean rightTypeFound() { 214 return fRightTypeFound; 215 } 216 217 private void setRightTypeFound(boolean value) { 218 fRightTypeFound= value; 219 } 220 221 public boolean hasError() { 222 return fError != null; 223 } 224 225 public void setError(String errorDesc) { 226 fError= errorDesc; 227 } 228 229 public String getError() { 230 return fError; 231 } 232 233 private StringBuffer buildRunMethod(List bodyDeclarations) { 234 StringBuffer buffer = new StringBuffer (); 235 236 if (fCreateInAStaticMethod) { 237 buffer.append("static "); if (isSourceLevelGreaterOrEqual(1, 5)) { 240 if (!fTypeParameters.isEmpty()) { 241 Iterator iterator = fTypeParameters.iterator(); 242 buffer.append(Signature.C_GENERIC_START); 243 while (iterator.hasNext()) { 244 String name = (String ) iterator.next(); 245 buffer.append(name); 246 if (iterator.hasNext()) { 247 buffer.append(", "); } 249 } 250 buffer.append(Signature.C_GENERIC_END); 251 } 252 } 253 } 254 255 buffer.append("void "); buffer.append(getUniqueMethodName(RUN_METHOD_NAME, bodyDeclarations)); 257 buffer.append('('); 258 for(int i= 0, length= fLocalVariableNames.length; i < length; i++) { 259 buffer.append(getDotName(fLocalVariableTypeNames[i])); 260 buffer.append(' '); 261 buffer.append(fLocalVariableNames[i]); 262 if (i + 1 < length) 263 buffer.append(", "); } 265 buffer.append(") throws Throwable {"); buffer.append('\n'); 267 fSnippetStartPosition= buffer.length() - 2; 268 fRunMethodStartOffset= fSnippetStartPosition; 269 String codeSnippet= new String (fCodeSnippet).trim(); 270 271 buffer.append(codeSnippet); 272 273 buffer.append('\n'); 274 buffer.append('}').append('\n'); 275 fRunMethodLength= buffer.length(); 276 return buffer; 277 } 278 279 private String getDotName(String typeName) { 280 return typeName.replace('$', '.'); 281 } 282 283 private boolean isRightType(ASTNode node) { 284 int position= getPosition(); 285 int startLineNumber= getCorrespondingLineNumber(node.getStartPosition()); 286 int endLineNumber= getCorrespondingLineNumber(node.getStartPosition() + node.getLength() - 1); 287 if (startLineNumber <= position && position <= endLineNumber) { 288 String typeName= fTypeName; 290 while (node != null) { 291 if (node instanceof TypeDeclaration || node instanceof EnumDeclaration) { 292 AbstractTypeDeclaration abstractTypeDeclaration= (AbstractTypeDeclaration) node; 293 String name= abstractTypeDeclaration.getName().getIdentifier(); 294 if (abstractTypeDeclaration.isLocalTypeDeclaration()) { 295 if (! typeName.endsWith('$' + name)) { 296 return false; 297 } 298 typeName= typeName.substring(0, typeName.length() - name.length() - 1); 299 int index= typeName.lastIndexOf('$'); 300 if (index < 0) { 301 return false; 302 } 303 for (int i= typeName.length() - 1; i > index; i--) { 304 if (!Character.isDigit(typeName.charAt(i))) { 305 return false; 306 } 307 } 308 typeName= typeName.substring(0, index); 309 ASTNode parent= node.getParent(); 310 while (!(parent instanceof CompilationUnit)) { 311 node= parent; 312 parent= node.getParent(); 313 } 314 } else { 315 if (abstractTypeDeclaration.isPackageMemberTypeDeclaration()) { 316 PackageDeclaration packageDeclaration= ((CompilationUnit) node.getParent()).getPackage(); 317 if (packageDeclaration == null) { 318 return typeName.equals(name); 319 } 320 return typeName.equals(getQualifiedIdentifier(packageDeclaration.getName()) + '.' + name); 321 } 322 if (!typeName.endsWith('$' + name)) { 323 return false; 324 } 325 typeName= typeName.substring(0, typeName.length() - name.length() - 1); 326 node= node.getParent(); 327 } 328 } else if (node instanceof ClassInstanceCreation) { 329 int index= typeName.lastIndexOf('$'); 330 if (index < 0) { 331 return false; 332 } 333 for (int i= typeName.length() - 1; i > index; i--) { 334 if (!Character.isDigit(typeName.charAt(i))) { 335 return false; 336 } 337 } 338 typeName= typeName.substring(0, index); 339 ASTNode parent= node.getParent(); 340 while (!(parent instanceof CompilationUnit)) { 341 node= parent; 342 parent= node.getParent(); 343 } 344 } 345 } 346 } 347 return false; 348 } 349 350 private StringBuffer buildTypeBody(StringBuffer buffer, List list) { 351 StringBuffer source = new StringBuffer (); 352 353 source.append('{').append('\n'); 354 355 if (buffer != null) { 356 fSnippetStartPosition+= source.length(); 357 } 358 359 source.append(buildBody(buffer, list)); 360 source.append('}').append('\n'); 361 362 return source; 363 } 364 365 private StringBuffer buildEnumBody(StringBuffer buffer, List constantDeclarations, List bodyDeclarations) { 366 StringBuffer source = new StringBuffer (); 367 368 source.append('{').append('\n'); 369 if (constantDeclarations.isEmpty()) { 370 source.append(';').append('\n'); 371 } else { 372 for (Iterator iter= constantDeclarations.iterator(); iter.hasNext();) { 373 source.append(((EnumConstantDeclaration) iter.next()).getName().getIdentifier()); 374 if (iter.hasNext()) { 375 source.append(','); 376 } else { 377 source.append(';'); 378 } 379 source.append('\n'); 380 } 381 } 382 383 if (buffer != null) { 384 fSnippetStartPosition+= source.length(); 385 } 386 387 source.append(buildBody(buffer, bodyDeclarations)); 388 source.append('}').append('\n'); 389 390 return source; 391 392 } 393 394 399 private StringBuffer buildBody(StringBuffer buffer, List list) { 400 StringBuffer source= new StringBuffer (); 401 if (buffer != null) { 402 fSnippetStartPosition += source.length(); 403 source.append(buffer.toString()); 404 } 405 for (Iterator iterator= list.iterator(); iterator.hasNext();) { 406 BodyDeclaration bodyDeclaration= (BodyDeclaration) iterator.next(); 407 if (bodyDeclaration instanceof FieldDeclaration) { 408 source.append(buildFieldDeclaration((FieldDeclaration) bodyDeclaration)); 409 } else if (bodyDeclaration instanceof MethodDeclaration) { 410 source.append(buildMethodDeclaration((MethodDeclaration) bodyDeclaration)); 411 } else if (bodyDeclaration instanceof TypeDeclaration) { 412 TypeDeclaration typeDeclaration = (TypeDeclaration) bodyDeclaration; 413 if (!typeDeclaration.getName().getIdentifier().equals(fLastTypeName)) { 414 source.append(buildTypeDeclaration(null, typeDeclaration)); 415 } 416 } else if (bodyDeclaration instanceof EnumDeclaration) { 417 EnumDeclaration enumDeclaration= (EnumDeclaration) bodyDeclaration; 418 if (!enumDeclaration.getName().getIdentifier().equals(fLastTypeName)) { 419 source.append(buildEnumDeclaration(null, enumDeclaration)); 420 } 421 } 422 } 423 return source; 424 } 425 426 private StringBuffer buildFieldDeclaration(FieldDeclaration fieldDeclaration) { 427 StringBuffer source = new StringBuffer (); 428 429 source.append(Flags.toString(fieldDeclaration.getModifiers())); 430 source.append(' '); 431 source.append(getDotName(getTypeName(fieldDeclaration.getType()))); 432 source.append(' '); 433 434 boolean first= true; 435 for (Iterator iterator= fieldDeclaration.fragments().iterator(); iterator.hasNext();) { 436 VariableDeclarationFragment variableDeclarationFragment= (VariableDeclarationFragment) iterator.next(); 437 if (first) { 438 first = false; 439 } else { 440 source.append(','); 441 } 442 source.append(variableDeclarationFragment.getName().getIdentifier()); 443 for (int i= 0, dim= variableDeclarationFragment.getExtraDimensions(); i < dim; i++) { 444 source.append('[').append(']'); 445 } 446 } 447 448 source.append(';').append('\n'); 449 450 return source; 451 } 452 453 private StringBuffer buildMethodDeclaration(MethodDeclaration methodDeclaration) { 454 StringBuffer source = new StringBuffer (); 455 int modifiers= methodDeclaration.getModifiers(); 456 source.append(Flags.toString(modifiers)); 457 source.append(' '); 458 459 appendTypeParameters(source, methodDeclaration.typeParameters()); 460 461 boolean isConstructor= methodDeclaration.isConstructor(); 462 if (!isConstructor) { 463 source.append(getDotName(getTypeName(methodDeclaration.getReturnType2()))); 464 source.append(' '); 465 } 466 467 source.append(methodDeclaration.getName().getIdentifier()); 468 source.append(' ').append('('); 469 470 boolean first= true; 471 for (Iterator iterator = methodDeclaration.parameters().iterator(); iterator.hasNext();) { 472 SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) iterator.next(); 473 if (first) { 474 first = false; 475 } else { 476 source.append(','); 477 } 478 source.append(getDotName(getTypeName(singleVariableDeclaration.getType()))); 479 if (singleVariableDeclaration.isVarargs()) { 480 source.append("..."); } 482 source.append(' '); 483 source.append(singleVariableDeclaration.getName().getIdentifier()); 484 appendExtraDimensions(source, singleVariableDeclaration.getExtraDimensions()); 485 } 486 487 source.append(')'); 488 489 appendExtraDimensions(source, methodDeclaration.getExtraDimensions()); 490 491 first = true; 492 for (Iterator iterator = methodDeclaration.thrownExceptions().iterator(); iterator.hasNext();) { 493 Name name = (Name) iterator.next(); 494 if (first) { 495 first = false; 496 source.append(" throws "); } else { 498 source.append(','); 499 } 500 source.append(getQualifiedIdentifier(name)); 501 } 502 503 if (Flags.isAbstract(modifiers) || Flags.isNative(modifiers)) { 504 source.append(";\n"); } else { 507 source.append('{').append('\n'); 508 if (!isConstructor) { 509 source.append(getReturnExpression(methodDeclaration.getReturnType2())); 510 } 511 source.append('}').append('\n'); 512 } 513 514 return source; 515 } 516 517 private void appendExtraDimensions(StringBuffer source, int extraDimension) { 518 if (extraDimension > 0) { 519 source.append(' '); 520 for (int i= 0; i < extraDimension; i ++) { 521 source.append("[]"); } 523 } 524 } 525 526 private StringBuffer buildEnumDeclaration(StringBuffer buffer, EnumDeclaration enumDeclaration) { 527 StringBuffer source = new StringBuffer (); 528 source.append(Flags.toString(enumDeclaration.getModifiers())); 529 source.append(" enum "); 531 source.append(enumDeclaration.getName().getIdentifier()); 532 533 Iterator iterator= enumDeclaration.superInterfaceTypes().iterator(); 534 if (iterator.hasNext()) { 535 source.append(" implements "); source.append(getTypeName((Type) iterator.next())); 537 while (iterator.hasNext()) { 538 source.append(','); 539 source.append(getTypeName((Type) iterator.next())); 540 } 541 } 542 543 if (buffer != null) { 544 fSnippetStartPosition+= source.length(); 545 } 546 source.append(buildEnumBody(buffer, enumDeclaration.enumConstants(), enumDeclaration.bodyDeclarations())); 547 548 return source; 549 } 550 551 552 private StringBuffer buildTypeDeclaration(StringBuffer buffer, TypeDeclaration typeDeclaration) { 553 554 StringBuffer source = new StringBuffer (); 555 source.append(Flags.toString(typeDeclaration.getModifiers())); 556 if (typeDeclaration.isInterface()) { 557 source.append(" interface "); } else { 559 source.append(" class "); } 561 562 source.append(typeDeclaration.getName().getIdentifier()); 563 564 List typeParameters= typeDeclaration.typeParameters(); 565 if (!typeParameters.isEmpty() && isSourceLevelGreaterOrEqual(1, 5)) { 566 source.append('<'); 567 Iterator iter= typeParameters.iterator(); 568 TypeParameter typeParameter= (TypeParameter) iter.next(); 569 source.append(typeParameter.getName().getIdentifier()); 570 List typeBounds= typeParameter.typeBounds(); 571 if (!typeBounds.isEmpty()) { 572 source.append(" extends "); Iterator iter2= typeBounds.iterator(); 574 source.append(getTypeName((Type) iter2.next())); 575 while (iter2.hasNext()) { 576 source.append('&'); 577 source.append(getTypeName((Type) iter2.next())); 578 } 579 } 580 while (iter.hasNext()) { 581 source.append(','); 582 typeParameter= (TypeParameter) iter.next(); 583 source.append(typeParameter.getName().getIdentifier()); 584 typeBounds= typeParameter.typeBounds(); 585 if (!typeBounds.isEmpty()) { 586 source.append(" extends "); Iterator iter2= typeBounds.iterator(); 588 source.append(getTypeName((Type) iter2.next())); 589 while (iter2.hasNext()) { 590 source.append('&'); 591 source.append(getTypeName((Type) iter2.next())); 592 } 593 } 594 } 595 source.append('>'); 596 } 597 598 Type superClass = typeDeclaration.getSuperclassType(); 599 if (superClass != null) { 600 source.append(" extends "); source.append(getTypeName(superClass)); 602 } 603 604 Iterator iter= typeDeclaration.superInterfaceTypes().iterator(); 605 if (iter.hasNext()) { 606 if (typeDeclaration.isInterface()) { 607 source.append(" extends "); } else { 609 source.append(" implements "); } 611 source.append(getTypeName((Type) iter.next())); 612 while (iter.hasNext()) { 613 source.append(','); 614 source.append(getTypeName((Type) iter.next())); 615 } 616 } 617 618 if (buffer != null) { 619 fSnippetStartPosition+= source.length(); 620 } 621 source.append(buildTypeBody(buffer, typeDeclaration.bodyDeclarations())); 622 623 return source; 624 } 625 626 private StringBuffer buildCompilationUnit(StringBuffer buffer, CompilationUnit compilationUnit) { 627 StringBuffer source = new StringBuffer (); 628 629 PackageDeclaration packageDeclaration = compilationUnit.getPackage(); 630 if (packageDeclaration != null) { 631 source.append("package "); source.append(getQualifiedIdentifier(packageDeclaration.getName())); 633 source.append(";\n"); } 635 636 for (Iterator iterator = compilationUnit.imports().iterator(); iterator.hasNext();) { 637 ImportDeclaration importDeclaration = (ImportDeclaration) iterator.next(); 638 source.append("import "); if (importDeclaration.isStatic()) { 640 source.append("static "); } 642 source.append(getQualifiedIdentifier(importDeclaration.getName())); 643 if (importDeclaration.isOnDemand()) { 644 source.append(".*"); } 646 source.append(";\n"); } 648 649 fSnippetStartPosition += source.length(); 650 source.append(buffer); 651 652 for (Iterator iterator = compilationUnit.types().iterator(); iterator.hasNext();) { 653 AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration) iterator.next(); 654 if (Flags.isPublic(typeDeclaration.getModifiers())) { 655 fCompilationUnitName = typeDeclaration.getName().getIdentifier(); 656 } 657 if (!fLastTypeName.equals(typeDeclaration.getName().getIdentifier())) { 658 if (typeDeclaration instanceof TypeDeclaration) { 659 source.append(buildTypeDeclaration(null, (TypeDeclaration)typeDeclaration)); 660 } else if (typeDeclaration instanceof EnumDeclaration) { 661 source.append(buildEnumDeclaration(null, (EnumDeclaration)typeDeclaration)); 662 } 663 } 664 } 665 if (fCompilationUnitName == null) { 666 fCompilationUnitName= "Eval"; } 670 return source; 671 } 672 673 678 private String getUniqueMethodName(String methodName, List bodyDeclarations) { 679 Iterator iter= bodyDeclarations.iterator(); 680 BodyDeclaration bodyDeclaration; 681 MethodDeclaration method; 682 String foundName; 683 while (iter.hasNext()) { 684 bodyDeclaration= (BodyDeclaration) iter.next(); 685 if (bodyDeclaration instanceof MethodDeclaration) { 686 method= (MethodDeclaration)bodyDeclaration; 687 foundName= method.getName().getIdentifier(); 688 if (foundName.startsWith(methodName)) { 689 methodName= foundName + '_'; 690 } 691 } 692 } 693 return methodName; 694 } 695 696 701 private String getUniqueFieldName(String fieldName, List bodyDeclarations) { 702 Iterator iter= bodyDeclarations.iterator(); 703 BodyDeclaration bodyDeclaration; 704 FieldDeclaration fieldDeclaration; 705 String foundName; 706 while (iter.hasNext()) { 707 bodyDeclaration= (BodyDeclaration) iter.next(); 708 if (bodyDeclaration instanceof FieldDeclaration) { 709 fieldDeclaration= (FieldDeclaration)bodyDeclaration; 710 for (Iterator iterator= fieldDeclaration.fragments().iterator(); iterator.hasNext();) { 711 foundName= ((VariableDeclarationFragment) iterator.next()).getName().getIdentifier(); 712 if (foundName.startsWith(fieldName)) { 713 fieldName= foundName + '_'; 714 } 715 } 716 } 717 } 718 return fieldName; 719 } 720 721 private String getQualifiedIdentifier(Name name) { 722 String typeName= ""; while (name.isQualifiedName()) { 724 QualifiedName qualifiedName = (QualifiedName) name; 725 typeName= "." + qualifiedName.getName().getIdentifier() + typeName; name= qualifiedName.getQualifier(); 727 } 728 if (name.isSimpleName()) { 729 typeName= ((SimpleName)name).getIdentifier() + typeName; 730 } else { 731 return null; 732 } 733 return typeName; 734 } 735 736 public String getTypeName(Type type) { 737 if (type.isSimpleType()) { 738 String name = getQualifiedIdentifier(((SimpleType) type).getName()); 739 if (!isSourceLevelGreaterOrEqual(1, 5) && fTypeParameters.contains(name)) { 740 return "Object"; } 742 return name; 743 } else if (type.isArrayType()) { 744 return getTypeName(((ArrayType) type).getComponentType()) + "[]"; } else if (type.isPrimitiveType()) { 746 return ((PrimitiveType) type).getPrimitiveTypeCode().toString(); 747 } else if (type.isQualifiedType()) { 748 QualifiedType qualifiedType= (QualifiedType) type; 749 return getTypeName(qualifiedType.getQualifier()) + '.' + qualifiedType.getName().getIdentifier(); 750 } else if (type.isParameterizedType()) { 751 ParameterizedType parameterizedType= (ParameterizedType)type; 752 StringBuffer buff= new StringBuffer (getTypeName(parameterizedType.getType())); 753 Iterator iter= parameterizedType.typeArguments().iterator(); 754 if (iter.hasNext() && isSourceLevelGreaterOrEqual(1, 5)) { 755 buff.append('<'); 756 buff.append(getTypeName((Type)iter.next())); 757 while (iter.hasNext()) { 758 buff.append(','); 759 buff.append(getTypeName((Type)iter.next())); 760 } 761 buff.append('>'); 762 } 763 return buff.toString(); 764 } else if (type.isWildcardType()) { 765 WildcardType wildcardType= (WildcardType)type; 766 StringBuffer buff= new StringBuffer ("?"); Type bound= wildcardType.getBound(); 768 if (bound != null) { 769 buff.append(wildcardType.isUpperBound() ? " extends " : " super "); buff.append(getTypeName(bound)); 771 } 772 return buff.toString(); 773 } 774 return null; 775 776 } 777 778 public String getReturnExpression(Type type) { 779 if (type.isSimpleType() || type.isArrayType() || type.isQualifiedType() || type.isWildcardType() || type.isParameterizedType()) { 780 return "return null;"; } else if (type.isPrimitiveType()) { 782 String typeName= ((PrimitiveType) type).getPrimitiveTypeCode().toString(); 783 char char0 = typeName.charAt(0); 784 if (char0 == 'v') { 785 return ""; } 787 char char1 = typeName.charAt(1); 788 if (char0 == 'b' && char1 == 'o') { 789 return "return false;"; } 791 return "return 0;"; } 793 return null; 794 } 795 796 797 799 802 public void endVisit(ClassInstanceCreation node) { 803 if (hasError()) { 804 return; 805 } 806 AnonymousClassDeclaration anonymousClassDeclaration = node.getAnonymousClassDeclaration(); 807 if (anonymousClassDeclaration != null) { 808 if (!rightTypeFound() && isRightType(node)) { 809 setRightTypeFound(true); 810 811 fSource= buildRunMethod(anonymousClassDeclaration.bodyDeclarations()); 812 fEvaluateNextEndTypeDeclaration = true; 813 } 814 815 if (rightTypeFound()) { 816 817 List bodyDeclarations= anonymousClassDeclaration.bodyDeclarations(); 818 819 StringBuffer source = buildTypeBody(fSource, bodyDeclarations); 820 821 ASTNode parent = node.getParent(); 822 while (!(parent instanceof MethodDeclaration || parent instanceof FieldDeclaration)) { 823 parent= parent.getParent(); 824 } 825 826 fSource= new StringBuffer (); 827 828 if (parent instanceof MethodDeclaration) { 829 MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) parent; 830 831 if (Flags.isStatic(enclosingMethodDeclaration.getModifiers())) { 832 fSource.append("static "); } 834 835 fSource.append("void "); fSource.append(getUniqueMethodName(EVAL_METHOD_NAME, bodyDeclarations)); 837 fSource.append("() {\n"); fSource.append("new "); fSource.append(getTypeName(node.getType())); 840 fSource.append("()"); 842 fSnippetStartPosition+= fSource.length(); 843 fSource.append(source); 844 fSource.append(";}\n"); 846 } else if (parent instanceof FieldDeclaration) { 847 FieldDeclaration enclosingFieldDeclaration = (FieldDeclaration) parent; 848 849 if (Flags.isStatic(enclosingFieldDeclaration.getModifiers())) { 850 fSource.append("static "); } 852 853 Type type= enclosingFieldDeclaration.getType(); 854 while (type instanceof ArrayType) { 855 type= ((ArrayType)type).getComponentType(); 856 } 857 858 fSource.append(getQualifiedIdentifier(((SimpleType)type).getName())); 859 fSource.append(' '); 860 fSource.append(getUniqueFieldName(EVAL_FIELD_NAME, bodyDeclarations)); 861 fSource.append(" = new "); fSource.append(getTypeName(node.getType())); 863 fSource.append("()"); 865 fSnippetStartPosition+= fSource.length(); 866 fSource.append(source); 867 fSource.append(";\n"); 869 } 870 fLastTypeName= ""; } 872 } 873 } 874 875 878 public void endVisit(CompilationUnit node) { 879 if (hasError()) { 880 return; 881 } 882 if (!rightTypeFound()) { fSource= null; 884 return; 885 } 886 fSource = buildCompilationUnit(fSource, node); 887 } 888 889 892 public void endVisit(EnumDeclaration node) { 893 894 if (hasError()) { 895 return; 896 } 897 898 if (!rightTypeFound() && isRightType(node)) { 899 setRightTypeFound(true); 900 901 fSource= buildRunMethod(node.bodyDeclarations()); 902 fEvaluateNextEndTypeDeclaration = true; 903 } 904 905 if (!fEvaluateNextEndTypeDeclaration) { 906 fEvaluateNextEndTypeDeclaration = true; 907 return; 908 } 909 910 if (rightTypeFound()) { 911 912 StringBuffer source = buildEnumDeclaration(fSource, node); 913 914 if (node.isLocalTypeDeclaration()) { 915 917 ASTNode parent = node.getParent(); 918 while (!(parent instanceof MethodDeclaration)) { 919 parent= parent.getParent(); 920 } 921 MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) parent; 922 923 fSource = new StringBuffer (); 924 925 if (Flags.isStatic(enclosingMethodDeclaration.getModifiers())) { 926 fSource.append("static "); } 928 929 fSource.append("void ___eval() {\n"); fSnippetStartPosition+= fSource.length(); 931 fSource.append(source); 932 fSource.append("}\n"); 934 fLastTypeName = ""; } else { 936 fSource = source; 937 fLastTypeName = node.getName().getIdentifier(); 938 } 939 } 940 } 941 942 945 public void endVisit(TypeDeclaration node) { 946 947 if (hasError()) { 948 return; 949 } 950 951 if (!rightTypeFound() && isRightType(node)) { 952 setRightTypeFound(true); 953 954 fSource= buildRunMethod(node.bodyDeclarations()); 955 fEvaluateNextEndTypeDeclaration = true; 956 } 957 958 if (!fEvaluateNextEndTypeDeclaration) { 959 fEvaluateNextEndTypeDeclaration = true; 960 return; 961 } 962 963 if (rightTypeFound()) { 964 965 StringBuffer source = buildTypeDeclaration(fSource, node); 966 967 if (node.isLocalTypeDeclaration()) { 968 970 ASTNode parent = node.getParent(); 971 while (!(parent instanceof MethodDeclaration)) { 972 parent= parent.getParent(); 973 } 974 MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) parent; 975 976 fSource = new StringBuffer (); 977 978 if (Flags.isStatic(enclosingMethodDeclaration.getModifiers())) { 979 fSource.append("static "); } 981 982 fSource.append("void ___eval() {\n"); fSnippetStartPosition+= fSource.length(); 984 fSource.append(source); 985 fSource.append("}\n"); 987 fLastTypeName = ""; } else { 989 fSource = source; 990 fLastTypeName = node.getName().getIdentifier(); 991 } 992 } 993 } 994 995 998 public boolean visit(AnnotationTypeDeclaration node) { 999 return false; 1000 } 1001 1002 1005 public boolean visit(AnnotationTypeMemberDeclaration node) { 1006 return false; 1007 } 1008 1009 1012 public boolean visit(AnonymousClassDeclaration node) { 1013 if (rightTypeFound()) { 1014 return false; 1015 } 1016 return true; 1017 } 1018 1019 1022 public boolean visit(ArrayAccess node) { 1023 if (rightTypeFound()) { 1024 return false; 1025 } 1026 return true; 1027 } 1028 1029 1032 public boolean visit(ArrayCreation node) { 1033 if (rightTypeFound()) { 1034 return false; 1035 } 1036 return true; 1037 } 1038 1039 1042 public boolean visit(ArrayInitializer node) { 1043 if (rightTypeFound()) { 1044 return false; 1045 } 1046 return true; 1047 } 1048 1049 1052 public boolean visit(ArrayType node) { 1053 if (rightTypeFound()) { 1054 return false; 1055 } 1056 return true; 1057 } 1058 1059 1062 public boolean visit(AssertStatement node) { 1063 if (rightTypeFound()) { 1064 return false; 1065 } 1066 return true; 1067 } 1068 1069 1072 public boolean visit(Assignment node) { 1073 if (rightTypeFound()) { 1074 return false; 1075 } 1076 return true; 1077 } 1078 1079 1082 public boolean visit(Block node) { 1083 if (rightTypeFound()) { 1084 return false; 1085 } 1086 return true; 1087 } 1088 1089 1092 public boolean visit(BlockComment node) { 1093 return false; 1094 } 1095 1096 1099 public boolean visit(BooleanLiteral node) { 1100 if (rightTypeFound()) { 1101 return false; 1102 } 1103 return true; 1104 } 1105 1106 1109 public boolean visit(BreakStatement node) { 1110 if (rightTypeFound()) { 1111 return false; 1112 } 1113 return true; 1114 } 1115 1116 1119 public boolean visit(CastExpression node) { 1120 if (rightTypeFound()) { 1121 return false; 1122 } 1123 return true; 1124 } 1125 1126 1129 public boolean visit(CatchClause node) { 1130 if (rightTypeFound()) { 1131 return false; 1132 } 1133 return true; 1134 } 1135 1136 1139 public boolean visit(CharacterLiteral node) { 1140 if (rightTypeFound()) { 1141 return false; 1142 } 1143 return true; 1144 } 1145 1146 1149 public boolean visit(ClassInstanceCreation node) { 1150 if (rightTypeFound()) { 1151 return false; 1152 } 1153 return true; 1154 } 1155 1156 1159 public boolean visit(CompilationUnit node) { 1160 if (rightTypeFound()) { 1161 return false; 1162 } 1163 return true; 1164 } 1165 1166 1169 public boolean visit(ConditionalExpression node) { 1170 if (rightTypeFound()) { 1171 return false; 1172 } 1173 return true; 1174 } 1175 1176 1179 public boolean visit(ConstructorInvocation node) { 1180 if (rightTypeFound()) { 1181 return false; 1182 } 1183 return true; 1184 } 1185 1186 1189 public boolean visit(ContinueStatement node) { 1190 if (rightTypeFound()) { 1191 return false; 1192 } 1193 return true; 1194 } 1195 1196 1199 public boolean visit(DoStatement node) { 1200 if (rightTypeFound()) { 1201 return false; 1202 } 1203 return true; 1204 } 1205 1206 1209 public boolean visit(EmptyStatement node) { 1210 if (rightTypeFound()) { 1211 return false; 1212 } 1213 return true; 1214 } 1215 1216 1219 public boolean visit(EnhancedForStatement node) { 1220 if (rightTypeFound()) { 1221 return false; 1222 } 1223 return true; 1224 } 1225 1226 1229 public boolean visit(EnumConstantDeclaration node) { 1230 if (rightTypeFound()) { 1231 return false; 1232 } 1233 return true; 1234 } 1235 1236 1239 public boolean visit(EnumDeclaration node) { 1240 if (rightTypeFound()) { 1241 return false; 1242 } 1243 return true; 1244 } 1245 1246 1249 public boolean visit(ExpressionStatement node) { 1250 if (rightTypeFound()) { 1251 return false; 1252 } 1253 return true; 1254 } 1255 1256 1259 public boolean visit(FieldAccess node) { 1260 if (rightTypeFound()) { 1261 return false; 1262 } 1263 return true; 1264 } 1265 1266 1269 public boolean visit(FieldDeclaration node) { 1270 if (rightTypeFound()) { 1271 return false; 1272 } 1273 return true; 1274 } 1275 1276 1279 public boolean visit(ForStatement node) { 1280 if (rightTypeFound()) { 1281 return false; 1282 } 1283 return true; 1284 } 1285 1286 1289 public boolean visit(IfStatement node) { 1290 if (rightTypeFound()) { 1291 return false; 1292 } 1293 return true; 1294 } 1295 1296 1299 public boolean visit(ImportDeclaration node) { 1300 if (rightTypeFound()) { 1301 return false; 1302 } 1303 return true; 1304 } 1305 1306 1309 public boolean visit(InfixExpression node) { 1310 if (rightTypeFound()) { 1311 return false; 1312 } 1313 return true; 1314 } 1315 1316 1319 public boolean visit(Initializer node) { 1320 if (rightTypeFound()) { 1321 return false; 1322 } 1323 return true; 1324 } 1325 1326 1329 public boolean visit(InstanceofExpression node) { 1330 if (rightTypeFound()) { 1331 return false; 1332 } 1333 return true; 1334 } 1335 1338 public boolean visit(Javadoc node) { 1339 if (rightTypeFound()) { 1340 return false; 1341 } 1342 return true; 1343 } 1344 1345 1348 public boolean visit(LabeledStatement node) { 1349 if (rightTypeFound()) { 1350 return false; 1351 } 1352 return true; 1353 } 1354 1355 1358 public boolean visit(LineComment node) { 1359 return false; 1360 } 1361 1362 1365 public boolean visit(MarkerAnnotation node) { 1366 return false; 1367 } 1368 1369 1372 public boolean visit(MemberRef node) { 1373 return false; 1374 } 1375 1376 1379 public boolean visit(MemberValuePair node) { 1380 return false; 1381 } 1382 1385 public boolean visit(MethodDeclaration node) { 1386 List typeParameters = node.typeParameters(); 1387 if (!typeParameters.isEmpty()) { 1388 Iterator iterator = typeParameters.iterator(); 1389 while (iterator.hasNext()) { 1390 TypeParameter typeParameter= (TypeParameter) iterator.next(); 1391 fTypeParameters.add(typeParameter.toString()); 1392 } 1393 } 1394 if (rightTypeFound()) { 1395 return false; 1396 } 1397 return true; 1398 } 1399 1400 1403 public boolean visit(MethodInvocation node) { 1404 if (rightTypeFound()) { 1405 return false; 1406 } 1407 return true; 1408 } 1409 1410 1413 public boolean visit(MethodRef node) { 1414 return false; 1415 } 1416 1417 1420 public boolean visit(MethodRefParameter node) { 1421 return false; 1422 } 1423 1424 1427 public boolean visit(Modifier node) { 1428 return false; 1429 } 1430 1431 1434 public boolean visit(NormalAnnotation node) { 1435 return false; 1436 } 1437 1438 1441 public boolean visit(NullLiteral node) { 1442 if (rightTypeFound()) { 1443 return false; 1444 } 1445 return true; 1446 } 1447 1448 1451 public boolean visit(NumberLiteral node) { 1452 if (rightTypeFound()) { 1453 return false; 1454 } 1455 return true; 1456 } 1457 1458 1461 public boolean visit(PackageDeclaration node) { 1462 if (rightTypeFound()) { 1463 return false; 1464 } 1465 return true; 1466 } 1467 1468 1471 public boolean visit(ParameterizedType node) { 1472 if (rightTypeFound()) { 1473 return false; 1474 } 1475 return true; 1476 } 1477 1478 1481 public boolean visit(ParenthesizedExpression node) { 1482 if (rightTypeFound()) { 1483 return false; 1484 } 1485 return true; 1486 } 1487 1488 1491 public boolean visit(PostfixExpression node) { 1492 if (rightTypeFound()) { 1493 return false; 1494 } 1495 return true; 1496 } 1497 1498 1501 public boolean visit(PrefixExpression node) { 1502 if (rightTypeFound()) { 1503 return false; 1504 } 1505 return true; 1506 } 1507 1508 1511 public boolean visit(PrimitiveType node) { 1512 if (rightTypeFound()) { 1513 return false; 1514 } 1515 return true; 1516 } 1517 1518 1521 public boolean visit(QualifiedName node) { 1522 if (rightTypeFound()) { 1523 return false; 1524 } 1525 return true; 1526 } 1527 1528 1531 public boolean visit(QualifiedType node) { 1532 return false; 1533 } 1534 1537 public boolean visit(ReturnStatement node) { 1538 if (rightTypeFound()) { 1539 return false; 1540 } 1541 return true; 1542 } 1543 1544 1547 public boolean visit(SimpleName node) { 1548 if (rightTypeFound()) { 1549 return false; 1550 } 1551 return true; 1552 } 1553 1554 1557 public boolean visit(SimpleType node) { 1558 if (rightTypeFound()) { 1559 return false; 1560 } 1561 return true; 1562 } 1563 1564 1567 public boolean visit(SingleMemberAnnotation node) { 1568 return false; 1569 } 1570 1571 1574 public boolean visit(SingleVariableDeclaration node) { 1575 if (rightTypeFound()) { 1576 return false; 1577 } 1578 return true; 1579 } 1580 1581 1584 public boolean visit(StringLiteral node) { 1585 if (rightTypeFound()) { 1586 return false; 1587 } 1588 return true; 1589 } 1590 1591 1594 public boolean visit(SuperConstructorInvocation node) { 1595 if (rightTypeFound()) { 1596 return false; 1597 } 1598 return true; 1599 } 1600 1601 1604 public boolean visit(SuperFieldAccess node) { 1605 if (rightTypeFound()) { 1606 return false; 1607 } 1608 return true; 1609 } 1610 1611 1614 public boolean visit(SuperMethodInvocation node) { 1615 if (rightTypeFound()) { 1616 return false; 1617 } 1618 return true; 1619 } 1620 1621 1624 public boolean visit(SwitchCase node) { 1625 if (rightTypeFound()) { 1626 return false; 1627 } 1628 return true; 1629 } 1630 1631 1634 public boolean visit(SwitchStatement node) { 1635 if (rightTypeFound()) { 1636 return false; 1637 } 1638 return true; 1639 } 1640 1641 1644 public boolean visit(SynchronizedStatement node) { 1645 if (rightTypeFound()) { 1646 return false; 1647 } 1648 return true; 1649 } 1650 1651 1654 public boolean visit(TagElement node) { 1655 return false; 1656 } 1657 1658 1661 public boolean visit(TextElement node) { 1662 return false; 1663 } 1664 1665 1668 public boolean visit(ThisExpression node) { 1669 if (rightTypeFound()) { 1670 return false; 1671 } 1672 return true; 1673 } 1674 1675 1678 public boolean visit(ThrowStatement node) { 1679 if (rightTypeFound()) { 1680 return false; 1681 } 1682 return true; 1683 } 1684 1685 1688 public boolean visit(TryStatement node) { 1689 if (rightTypeFound()) { 1690 return false; 1691 } 1692 return true; 1693 } 1694 1695 1698 public boolean visit(TypeDeclaration node) { 1699 List typeParameters = node.typeParameters(); 1700 if (!typeParameters.isEmpty()) { 1701 Iterator iterator = typeParameters.iterator(); 1702 while (iterator.hasNext()) { 1703 TypeParameter typeParameter= (TypeParameter) iterator.next(); 1704 fTypeParameters.add(typeParameter.getName().getIdentifier()); 1705 } 1706 } 1707 if (rightTypeFound()) { 1708 fEvaluateNextEndTypeDeclaration = false; 1709 return false; 1710 } 1711 return true; 1712 } 1713 1714 1717 public boolean visit(TypeDeclarationStatement node) { 1718 if (rightTypeFound()) { 1719 return false; 1720 } 1721 return true; 1722 } 1723 1724 1727 public boolean visit(TypeLiteral node) { 1728 if (rightTypeFound()) { 1729 return false; 1730 } 1731 return true; 1732 } 1733 1734 1737 public boolean visit(TypeParameter node) { 1738 return false; 1739 } 1740 1741 1744 public boolean visit(VariableDeclarationExpression node) { 1745 if (rightTypeFound()) { 1746 return false; 1747 } 1748 return true; 1749 } 1750 1751 1754 public boolean visit(VariableDeclarationFragment node) { 1755 if (rightTypeFound()) { 1756 return false; 1757 } 1758 return true; 1759 } 1760 1761 1764 public boolean visit(VariableDeclarationStatement node) { 1765 if (rightTypeFound()) { 1766 return false; 1767 } 1768 return true; 1769 } 1770 1771 1774 public boolean visit(WhileStatement node) { 1775 if (rightTypeFound()) { 1776 return false; 1777 } 1778 return true; 1779 } 1780 1781 1784 public boolean visit(WildcardType node) { 1785 return false; 1786 } 1787 1788 1796 public boolean isSourceLevelGreaterOrEqual(int major, int minor) { 1797 return (fSourceMajorLevel > major) || 1798 (fSourceMajorLevel == major && fSourceMinorLevel >= minor); 1799 } 1800 1801 1807 private void appendTypeParameters(StringBuffer source, List typeParameters) { 1808 if (!typeParameters.isEmpty() && isSourceLevelGreaterOrEqual(1, 5)) { 1809 source.append('<'); 1810 Iterator iter= typeParameters.iterator(); 1811 TypeParameter typeParameter= (TypeParameter) iter.next(); 1812 source.append(typeParameter.getName().getIdentifier()); 1813 List typeBounds= typeParameter.typeBounds(); 1814 if (!typeBounds.isEmpty()) { 1815 source.append(" extends "); Iterator iter2= typeBounds.iterator(); 1817 source.append(getTypeName((Type) iter2.next())); 1818 while (iter2.hasNext()) { 1819 source.append('&'); 1820 source.append(getTypeName((Type) iter2.next())); 1821 } 1822 } 1823 while (iter.hasNext()) { 1824 source.append(','); 1825 typeParameter= (TypeParameter) iter.next(); 1826 source.append(typeParameter.getName().getIdentifier()); 1827 typeBounds= typeParameter.typeBounds(); 1828 if (!typeBounds.isEmpty()) { 1829 source.append(" extends "); Iterator iter2= typeBounds.iterator(); 1831 source.append(getTypeName((Type) iter2.next())); 1832 while (iter2.hasNext()) { 1833 source.append('&'); 1834 source.append(getTypeName((Type) iter2.next())); 1835 } 1836 } 1837 } 1838 source.append('>'); 1839 source.append(' '); 1840 } 1841 } 1842} 1843 | Popular Tags |