001 /* 002 * Copyright (C) 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.codehaus.gmaven.runtime.support.stubgen.render; 018 019 import org.codehaus.gmaven.runtime.support.stubgen.model.ClassDef; 020 import org.codehaus.gmaven.runtime.support.stubgen.model.ConstructorDef; 021 import org.codehaus.gmaven.runtime.support.stubgen.model.EnumConstantDef; 022 import org.codehaus.gmaven.runtime.support.stubgen.model.EnumDef; 023 import org.codehaus.gmaven.runtime.support.stubgen.model.FieldDef; 024 import org.codehaus.gmaven.runtime.support.stubgen.model.ImportDef; 025 import org.codehaus.gmaven.runtime.support.stubgen.model.JavaDocAware; 026 import org.codehaus.gmaven.runtime.support.stubgen.model.JavaDocDef; 027 import org.codehaus.gmaven.runtime.support.stubgen.model.MethodDef; 028 import org.codehaus.gmaven.runtime.support.stubgen.model.ModifiersAware; 029 import org.codehaus.gmaven.runtime.support.stubgen.model.ModifiersDef; 030 import org.codehaus.gmaven.runtime.support.stubgen.model.PackageDef; 031 import org.codehaus.gmaven.runtime.support.stubgen.model.ParameterDef; 032 import org.codehaus.gmaven.runtime.support.stubgen.model.SuperParameterDef; 033 import org.codehaus.gmaven.runtime.support.stubgen.model.TagDef; 034 import org.codehaus.gmaven.runtime.support.stubgen.model.TypeDef; 035 036 import java.io.BufferedReader; 037 import java.io.IOException; 038 import java.io.PrintWriter; 039 import java.io.StringReader; 040 import java.io.Writer; 041 import java.util.HashMap; 042 import java.util.Iterator; 043 import java.util.Map; 044 import java.util.Set; 045 046 /** 047 * Provides support for {@link Renderer} implementations. 048 * 049 * @version $Id: RendererSupport.java 18 2009-07-16 09:39:40Z user57 $ 050 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 051 */ 052 public class RendererSupport 053 implements Renderer 054 { 055 protected final ClassDef clazz; 056 057 protected final Map importAliases = new HashMap(); 058 059 protected final Map definedMethods = new HashMap(); 060 061 protected RendererSupport(final ClassDef clazz) { 062 assert clazz != null; 063 064 this.clazz = clazz; 065 066 assert clazz.getParent() != null; 067 068 // Create a map of method signatures for quick lookup resolution 069 Iterator iter = clazz.getMethods().iterator(); 070 while (iter.hasNext()) { 071 MethodDef method = (MethodDef)iter.next(); 072 073 definedMethods.put(method.signature(), method); 074 } 075 } 076 077 public void render(final Writer writer) throws IOException { 078 assert writer != null; 079 080 PrintWriter out = new PrintWriter(writer); 081 082 renderHeader(out); 083 084 renderPackage(out); 085 086 renderImports(out); 087 088 renderClass(out); 089 090 out.flush(); 091 } 092 093 public String getName() { 094 return clazz.getName(); 095 } 096 097 public String getPackage() { 098 PackageDef pkg = clazz.getPackage(); 099 if (pkg != null) { 100 return pkg.getName(); 101 } 102 return null; 103 } 104 105 // 106 // Rendering 107 // 108 109 protected void renderHeader(final PrintWriter out) { 110 assert out != null; 111 112 // TODO: Should try to include the legal headers from the source here if we can parse them out 113 114 out.println("//"); 115 out.println("// Generated stub from " + clazz.getParent().getUrl()); 116 out.println("//"); 117 out.println(); 118 } 119 120 protected void renderPackage(final PrintWriter out) { 121 assert out != null; 122 123 PackageDef def = clazz.getPackage(); 124 125 if (def != null) { 126 out.print("package "); 127 out.print(def.getName()); 128 out.println(";"); 129 } 130 else { 131 out.println("// Default package"); 132 } 133 134 out.println(); 135 } 136 137 protected void renderImports(final PrintWriter out) { 138 assert out != null; 139 140 Set imports = clazz.getImports(); 141 assert imports != null; 142 143 if (!imports.isEmpty()) { 144 Iterator iter = imports.iterator(); 145 146 while (iter.hasNext()) { 147 ImportDef def = (ImportDef)iter.next(); 148 149 renderImport(out, def); 150 } 151 152 out.println(); 153 } 154 } 155 156 protected void renderImport(final PrintWriter out, final ImportDef def) { 157 assert out != null; 158 assert def != null; 159 160 // If the import is an alias (import as) then add to the mapping and omit rendering import 161 // will use the fully qualified name of the type when the alias is encoutnered 162 163 String alias = def.getAlias(); 164 if (alias != null) { 165 importAliases.put(alias, def); 166 167 out.print("// Import alias '"); 168 out.print(alias); 169 out.print("' will resolve to the full-qualified name: "); 170 out.println(def.getQualifiedName()); 171 172 return; 173 } 174 175 out.print("import "); 176 177 if (def.isStatic()) { 178 out.print("static "); 179 } 180 181 out.print(def.getQualifiedName()); 182 183 if (def.isWildcard()) { 184 out.print(".*"); 185 } 186 187 out.println(";"); 188 } 189 190 protected void renderType(final PrintWriter out, TypeDef def) { 191 assert out != null; 192 assert def != null; 193 194 String name = def.getName(); 195 196 if (name == null) { 197 name = TypeDef.OBJECT; 198 } 199 else { 200 ImportDef alias = (ImportDef)importAliases.get(name); 201 202 if (alias != null) { 203 name = alias.getQualifiedName(); 204 } 205 } 206 207 out.print(name); 208 209 int dimensions = def.getDimensions(); 210 211 for (int i=0; i < dimensions; i++) { 212 out.print("[]"); 213 } 214 } 215 216 protected void renderTypeSet(final PrintWriter out, final Set types) { 217 assert out != null; 218 assert types != null; 219 220 Iterator iter = types.iterator(); 221 222 while (iter.hasNext()) { 223 TypeDef def = (TypeDef)iter.next(); 224 renderType(out, def); 225 226 if (iter.hasNext()) { 227 out.print(", "); 228 } 229 } 230 } 231 232 protected void renderModifiers(final PrintWriter out, final ModifiersAware source) { 233 assert out != null; 234 assert source != null; 235 236 ModifiersDef modifiers = source.getModifiers(); 237 assert modifiers != null; 238 239 Set values = modifiers.getValues(); 240 241 if (!values.isEmpty()) { 242 Iterator iter = values.iterator(); 243 244 while (iter.hasNext()) { 245 String modifier = (String)iter.next(); 246 247 out.print(modifier); 248 249 if (iter.hasNext()) { 250 out.print(" "); 251 } 252 } 253 254 out.print(" "); 255 } 256 } 257 258 protected void renderJavaDoc(final PrintWriter out, final JavaDocAware source, final String indent) { 259 assert out != null; 260 assert source != null; 261 assert indent != null; 262 263 JavaDocDef def = source.getJavaDoc(); 264 265 if (def != null) { 266 out.print(indent); 267 out.println("/**"); 268 269 String comment = def.getComment(); 270 271 if (comment != null) { 272 comment = comment.trim(); 273 274 if (comment.length() > 0) { 275 BufferedReader reader = new BufferedReader(new StringReader(comment)); 276 277 String line; 278 try { 279 while ((line = reader.readLine()) != null) { 280 out.print(indent); 281 out.print(" * "); 282 out.println(line); 283 } 284 } 285 catch (IOException e) { 286 throw new InternalError("Failed to process JavaDoc comment string: " + comment); // Should never happen 287 } 288 } 289 } 290 291 Set tags = def.getTags(); 292 assert tags != null; 293 294 if (!tags.isEmpty()) { 295 // Add blank if we have a coment 296 if (comment != null && comment.length() > 0) { 297 out.print(indent); 298 out.println(" *"); 299 } 300 301 Iterator iter = tags.iterator(); 302 303 while (iter.hasNext()) { 304 TagDef tag = (TagDef)iter.next(); 305 306 out.print(indent); 307 out.print(" * @"); 308 out.print(tag.getName()); 309 310 String value = tag.getValue(); 311 if (value != null && value.length() > 0) { 312 out.print(" "); 313 out.print(value); 314 } 315 316 out.println(); 317 } 318 } 319 320 out.print(indent); 321 out.println(" */"); 322 } 323 } 324 325 protected void renderClass(final PrintWriter out) { 326 assert out != null; 327 328 renderJavaDoc(out, clazz, ""); 329 330 // TODO: May want to clone the modifiers to prevent augmenting the model 331 332 ModifiersDef modifiers = clazz.getModifiers(); 333 if (!modifiers.hasAccessModifiers()) { 334 modifiers.add(ModifiersDef.PUBLIC); 335 } 336 337 renderModifiers(out, clazz); 338 339 ClassDef.Type type = clazz.getType(); 340 assert type != null; 341 342 out.print(type); 343 out.print(" "); 344 out.println(clazz.getName()); 345 346 switch (type.code) { 347 348 case ClassDef.Type.CLASS_CODE: 349 case ClassDef.Type.ENUM_CODE: 350 { 351 TypeDef superClass = clazz.getSuperClass(); 352 if (superClass != null) { 353 out.print(" extends "); 354 renderType(out, superClass); 355 out.println(); 356 } 357 358 Set implementz = clazz.getImplements(); 359 assert implementz != null; 360 361 if (!implementz.isEmpty()) { 362 out.print(" implements "); 363 renderTypeSet(out, implementz); 364 out.println(); 365 } 366 } 367 break; 368 369 case ClassDef.Type.INTERFACE_CODE: 370 case ClassDef.Type.ANNOTATION_CODE: 371 { 372 Set implementz = clazz.getImplements(); 373 assert implementz != null; 374 375 if (!implementz.isEmpty()) { 376 out.print(" extends "); 377 renderTypeSet(out, implementz); 378 out.println(); 379 } 380 } 381 break; 382 383 default: 384 throw new InternalError("Invalid class type: " + type); // Should never happen 385 } 386 387 out.println("{"); 388 389 if (type.code == ClassDef.Type.ENUM_CODE) { 390 renderEnumConstants(out); 391 } 392 393 renderFields(out); 394 395 // Seperator only if we have both fields and methods 396 if (!clazz.getFields().isEmpty() && !clazz.getMethods().isEmpty()) { 397 out.println(); 398 } 399 400 renderMethods(out); 401 402 // TODO: See when we need to set this and when it could be harmful? 403 404 // Render synthetic methods 405 if (!clazz.isInterface() && !clazz.isAnnotation()) { 406 // Seperator if we have fields or methods 407 if (!clazz.getFields().isEmpty() || !clazz.getMethods().isEmpty()) { 408 out.println(); 409 } 410 411 renderSyntheticMethods(out); 412 } 413 414 out.println("}"); 415 } 416 417 protected void renderEnumConstants(final PrintWriter out) { 418 assert out != null; 419 420 Set constants = ((EnumDef)clazz).getConstants(); 421 assert constants != null; 422 423 if (!constants.isEmpty()) { 424 out.print(" "); 425 426 Iterator iter = constants.iterator(); 427 428 while (iter.hasNext()) { 429 EnumConstantDef def = (EnumConstantDef)iter.next(); 430 431 // TODO: Javadocs? 432 433 out.print(def.getName()); 434 435 // 436 // TODO: Need to render initalizers 437 // 438 439 if (iter.hasNext()) { 440 out.print(", "); 441 } 442 } 443 444 out.println(";"); 445 out.println(); 446 } 447 } 448 449 protected void renderFields(final PrintWriter out) { 450 assert out != null; 451 452 Set fields = clazz.getFields(); 453 assert fields != null; 454 455 if (!fields.isEmpty()) { 456 Iterator iter = fields.iterator(); 457 458 while (iter.hasNext()) { 459 FieldDef def = (FieldDef)iter.next(); 460 461 if (def.isProperty()) { 462 renderProperty(out, def); 463 } 464 else { 465 renderField(out, def); 466 } 467 468 if (iter.hasNext()) { 469 out.println(); 470 } 471 } 472 } 473 } 474 475 protected void renderField(final PrintWriter out, final FieldDef def) { 476 assert out != null; 477 assert def != null; 478 479 renderJavaDoc(out, def, " "); 480 481 out.print(" "); 482 483 if (!def.getParent().isInterface()) { 484 renderModifiers(out, def); 485 } 486 487 TypeDef type = def.getType(); 488 489 renderType(out, type); 490 491 out.print(" "); 492 493 out.print(def.getName()); 494 495 // TODO: See when we need to set this and when it could be harmful? 496 497 out.print(" = "); 498 out.print(type.getDefaultValue()); 499 500 out.println(";"); 501 } 502 503 protected void renderProperty(final PrintWriter out, final FieldDef def) { 504 assert out != null; 505 assert def != null; 506 assert def.isProperty(); 507 508 // Render private field, w/original javadocs 509 FieldDef field = new FieldDef(); 510 field.setParent(def.getParent()); 511 field.setJavaDoc(def.getJavaDoc()); 512 field.setType(def.getType()); 513 field.setName(def.getName()); 514 field.getModifiers().merge(def.getModifiers()).add(ModifiersDef.PRIVATE); 515 renderField(out, field); 516 517 String name = capitalize(def.getName()); 518 519 // Setup the modifiers for property methods 520 ModifiersDef modifiers = def.getModifiers(); 521 modifiers.add(ModifiersDef.PUBLIC); 522 modifiers.remove(ModifiersDef.TRANSIENT).remove(ModifiersDef.VOLATILE); 523 524 MethodDef getter = new MethodDef(); 525 getter.setParent(def.getParent()); 526 getter.setName("get" + name); 527 getter.setReturns(def.getType()); 528 getter.getModifiers().merge(modifiers); 529 530 if (!definedMethods.containsKey(getter.signature())) { 531 renderMethod(out, getter); 532 } 533 534 if (def.getType().isBoolean()) { 535 MethodDef isser = new MethodDef(); 536 isser.setParent(def.getParent()); 537 isser.setName("is" + name); 538 isser.setReturns(def.getType()); 539 isser.getModifiers().merge(modifiers); 540 541 if (!definedMethods.containsKey(isser.signature())) { 542 renderMethod(out, isser); 543 } 544 } 545 546 if (!def.getModifiers().isFinal()) { 547 MethodDef setter = new MethodDef(); 548 setter.setParent(def.getParent()); 549 setter.setName("set" + name); 550 setter.setReturns(TypeDef.VOID); 551 setter.addParameter(def.getType(), "value"); 552 setter.getModifiers().merge(modifiers); 553 554 if (!definedMethods.containsKey(setter.signature())) { 555 renderMethod(out, setter); 556 } 557 } 558 } 559 560 protected String capitalize(final String string) { 561 assert string != null; 562 563 int length = string.length(); 564 565 if (length == 0) { 566 return string; 567 } 568 else if (length == 1) { 569 return string.toUpperCase(); 570 } 571 else { 572 return (Character.toUpperCase(string.charAt(0)) + string.substring(1)); 573 } 574 } 575 576 protected void renderSyntheticMethods(final PrintWriter out) { 577 assert out != null; 578 579 MethodDef def; 580 581 // 582 // FIXME: Should these already be configured in the model, since every Class must implement GroovyObject? 583 // 584 585 /* 586 java.lang.Object invokeMethod(java.lang.String s, java.lang.Object o); 587 588 java.lang.Object getProperty(java.lang.String s); 589 590 void setProperty(java.lang.String s, java.lang.Object o); 591 592 groovy.lang.MetaClass getMetaClass(); 593 594 void setMetaClass(groovy.lang.MetaClass metaClass); 595 */ 596 597 def = new MethodDef(); 598 def.setParent(clazz); 599 def.getModifiers().add(ModifiersDef.PUBLIC); 600 def.setReturns("groovy.lang.MetaClass"); 601 def.setName("getMetaClass"); 602 603 if (!definedMethods.containsKey(def.signature())) { 604 renderMethod(out, def); 605 out.println(); 606 } 607 608 def = new MethodDef(); 609 def.setParent(clazz); 610 def.getModifiers().add(ModifiersDef.PUBLIC); 611 def.setReturns(TypeDef.VOID); 612 def.setName("setMetaClass"); 613 def.addParameter("groovy.lang.MetaClass", "metaClass"); 614 615 if (!definedMethods.containsKey(def.signature())) { 616 renderMethod(out, def); 617 out.println(); 618 } 619 620 def = new MethodDef(); 621 def.setParent(clazz); 622 def.getModifiers().add(ModifiersDef.PUBLIC); 623 def.setReturns(TypeDef.OBJECT); 624 def.setName("invokeMethod"); 625 def.addParameter(TypeDef.STRING, "name"); 626 def.addParameter(TypeDef.OBJECT, "args"); 627 628 if (!definedMethods.containsKey(def.signature())) { 629 renderMethod(out, def); 630 out.println(); 631 } 632 633 def = new MethodDef(); 634 def.setParent(clazz); 635 def.getModifiers().add(ModifiersDef.PUBLIC); 636 def.setReturns(TypeDef.OBJECT); 637 def.setName("getProperty"); 638 def.addParameter(TypeDef.STRING, "name"); 639 640 if (!definedMethods.containsKey(def.signature())) { 641 renderMethod(out, def); 642 out.println(); 643 } 644 645 def = new MethodDef(); 646 def.setParent(clazz); 647 def.getModifiers().add(ModifiersDef.PUBLIC); 648 def.setReturns(TypeDef.VOID); 649 def.setName("setProperty"); 650 def.addParameter(TypeDef.STRING, "name"); 651 def.addParameter(TypeDef.OBJECT, "value"); 652 653 if (!definedMethods.containsKey(def.signature())) { 654 renderMethod(out, def); 655 } 656 } 657 658 protected void renderMethods(final PrintWriter out) { 659 assert out != null; 660 661 if (!clazz.isInterface()) { 662 renderMagicConstructors(out); 663 } 664 665 Set methods = clazz.getMethods(); 666 assert methods != null; 667 668 if (!methods.isEmpty()) { 669 Iterator iter = methods.iterator(); 670 671 while (iter.hasNext()) { 672 MethodDef def = (MethodDef)iter.next(); 673 renderMethod(out, def); 674 675 if (iter.hasNext()) { 676 out.println(); 677 } 678 } 679 } 680 } 681 682 protected ConstructorDef createMagicConstructor() { 683 ConstructorDef def = new ConstructorDef(true); 684 def.setParent(clazz); 685 def.getModifiers().add(ModifiersDef.PRIVATE); 686 def.setJavaDoc("Magic constructor"); 687 688 // Add insane params which no one would ever use... :-( 689 def.addParameter("java.lang.Void", "void0"); 690 def.addParameter("java.lang.Void", "void1"); 691 def.addParameter("java.lang.Void", "void2"); 692 693 // 694 // NOTE: This must match up with what is invoked in {@link #renderMagicConstructorInvoke} 695 // 696 697 return def; 698 } 699 700 protected void renderMagicConstructorInvoke(final PrintWriter out, final ConstructorDef def) { 701 assert out != null; 702 assert def != null; 703 704 out.print(" this((java.lang.Void)null, (java.lang.Void)null, (java.lang.Void)null"); 705 706 // If the given constructor declares throwables, then invoke correct magic constructor 707 Iterator iter = def.getThrows().iterator(); 708 while (iter.hasNext()) { 709 TypeDef type = (TypeDef)iter.next(); 710 out.print(", "); 711 out.print("("); 712 out.print(type.getName()); 713 out.print(")null"); 714 } 715 716 out.println(");"); 717 } 718 719 protected void renderMagicConstructors(final PrintWriter out) { 720 assert out != null; 721 722 // Only render magic constructors if there are other constructors defined 723 if (!clazz.getConstructors().isEmpty()) { 724 int count=0; 725 726 // Generate magic constructor for constructors with a throws clauses. 727 Iterator iter = clazz.getConstructors().iterator(); 728 while (iter.hasNext()) { 729 ConstructorDef ctor = (ConstructorDef)iter.next(); 730 if (!ctor.getThrows().isEmpty()) { 731 // Add a magic constructor based on the default, adding a parameter for each throwable in the list 732 Iterator iter2 = ctor.getThrows().iterator(); 733 ConstructorDef def = createMagicConstructor(); 734 def.getThrows().addAll(ctor.getThrows()); 735 736 int i=0; 737 while (iter2.hasNext()) { 738 TypeDef type = (TypeDef)iter2.next(); 739 def.addParameter(type.getName(), "cause" + i++); 740 } 741 742 renderMethod(out, def); 743 out.println(); 744 745 count++; 746 } 747 } 748 749 // Generate the default magic constructor, if we didn't generate any others 750 if (count == 0) { 751 renderMethod(out, createMagicConstructor()); 752 out.println(); 753 } 754 } 755 } 756 757 protected void renderMethod(final PrintWriter out, final MethodDef def) { 758 assert out != null; 759 assert def != null; 760 761 MethodDef.Type type = def.getType(); 762 763 renderJavaDoc(out, def, " "); 764 765 out.print(" "); 766 767 if (!def.getParent().isInterface()) { 768 // TODO: May want to clone the modifiers to prevent augmenting the model 769 770 ModifiersDef modifiers = def.getModifiers(); 771 if (!modifiers.hasAccessModifiers()) { 772 modifiers.add(ModifiersDef.PUBLIC); 773 } 774 775 renderModifiers(out, def); 776 } 777 778 if (type == MethodDef.Type.METHOD) { 779 renderType(out, def.getReturns()); 780 out.print(" "); 781 } 782 783 out.print(def.getName()); 784 785 out.print("("); 786 787 renderParameters(out, def.getParameters()); 788 789 out.print(")"); 790 791 Set throwz = def.getThrows(); 792 assert throwz != null; 793 794 if (!throwz.isEmpty()) { 795 out.print(" throws "); 796 renderTypeSet(out, throwz); 797 } 798 799 if (def.getParent().isAnnotation()) { 800 // 801 // TODO: Render default muck 802 // 803 804 out.println(";"); 805 } 806 else if (def.getParent().isInterface() || def.getModifiers().isAbstract() || def.getModifiers().isNative()) { 807 out.println(";"); 808 } 809 else { 810 out.println(" {"); 811 812 if (def.isConstructor()) { 813 assert def instanceof ConstructorDef; 814 815 ConstructorDef ctor = (ConstructorDef)def; 816 817 if (ctor.isMagic()) { 818 renderMagicConstructorSuper(out, ctor); 819 } 820 else { 821 renderMagicConstructorInvoke(out, ctor); 822 } 823 } 824 825 out.println(" throw new InternalError(\"Stubbed method\");"); 826 827 out.println(" }"); 828 } 829 } 830 831 protected void renderMagicConstructorSuper(final PrintWriter out, final ConstructorDef def) { 832 assert out != null; 833 assert def != null; 834 835 Set parameters = selectMagicConstructorSuperParameters(def); 836 837 if (parameters != null) { 838 out.print(" super"); 839 out.print("("); 840 841 if (!parameters.isEmpty()) { 842 Iterator iter = parameters.iterator(); 843 844 while (iter.hasNext()) { 845 SuperParameterDef param = (SuperParameterDef)iter.next(); 846 renderSuperParameter(out, param); 847 848 if (iter.hasNext()) { 849 out.print(", "); 850 } 851 } 852 } 853 854 out.println(");"); 855 out.println(); 856 } 857 } 858 859 protected Set selectMagicConstructorSuperParameters(final ConstructorDef target) { 860 assert target != null; 861 862 Iterator iter = target.getParent().getConstructors().iterator(); 863 864 // 865 // TODO: If we can't find one that is fully typed, perhaps we should pick the next best? 866 // 867 868 FIND_MAGIC_CTOR: 869 870 while (iter.hasNext()) { 871 ConstructorDef def = (ConstructorDef)iter.next(); 872 873 if (!def.isMagic() && "super".equals(def.getSuperType())) { 874 Set parameters = def.getSuperParameters(); 875 876 if (parameters != null && !parameters.isEmpty()) { 877 Iterator iter2 = parameters.iterator(); 878 879 while (iter2.hasNext()) { 880 SuperParameterDef param = (SuperParameterDef)iter2.next(); 881 882 if (param.getType() == null) { 883 continue FIND_MAGIC_CTOR; 884 } 885 } 886 887 return parameters; 888 } 889 } 890 } 891 892 return null; 893 } 894 895 protected void renderSuperParameters(final PrintWriter out, final ConstructorDef def) { 896 assert out != null; 897 assert def != null; 898 899 String superType = def.getSuperType(); 900 901 if (superType != null) { 902 903 out.print(" "); 904 out.print(superType); 905 out.print("("); 906 907 Set params = def.getSuperParameters(); 908 909 if (!params.isEmpty()) { 910 Iterator iter = params.iterator(); 911 912 while (iter.hasNext()) { 913 SuperParameterDef param = (SuperParameterDef)iter.next(); 914 renderSuperParameter(out, param); 915 916 if (iter.hasNext()) { 917 out.print(", "); 918 } 919 } 920 } 921 922 out.println(");"); 923 out.println(); 924 } 925 } 926 927 protected void renderSuperParameter(final PrintWriter out, final SuperParameterDef def) { 928 assert out != null; 929 assert def != null; 930 931 TypeDef type = def.getType(); 932 if (type == null) { 933 // This is probably this, null or some dot expression, which needs to be handled better 934 out.print(TypeDef.NULL); 935 } 936 else { 937 out.print("("); 938 renderType(out, type); 939 out.print(")"); 940 out.print(type.getDefaultValue()); 941 } 942 } 943 944 protected void renderParameters(final PrintWriter out, final Set parameters) { 945 assert out != null; 946 assert parameters != null; 947 948 Iterator iter = parameters.iterator(); 949 950 while (iter.hasNext()) { 951 ParameterDef def = (ParameterDef)iter.next(); 952 953 renderParameter(out, def); 954 955 if (iter.hasNext()) { 956 out.print(", "); 957 } 958 } 959 } 960 961 protected void renderParameter(final PrintWriter out, final ParameterDef def) { 962 assert out != null; 963 assert def != null; 964 965 if (!def.getParent().getParent().isInterface()) { 966 renderModifiers(out, def); 967 } 968 969 renderType(out, def.getType()); 970 971 out.print(" "); 972 973 out.print(def.getName()); 974 } 975 }