1 module dparse.formatter; 2 3 import std.algorithm; 4 import std.range; 5 import std.stdio; 6 import std.typetuple:TypeTuple; 7 8 import dparse.ast; 9 import dparse.lexer; 10 11 //debug = verbose; 12 13 /** 14 * The only brace styles worth using. 15 */ 16 enum IndentStyle 17 { 18 /** 19 * --- 20 * if (something) 21 * { 22 * foo(); 23 * bar(); 24 * } 25 * else 26 * { 27 * bar(); 28 * baz(); 29 * } 30 * --- 31 */ 32 allman, 33 /** 34 * --- 35 * if (something) { 36 * foo(); 37 * bar(); 38 * } else { 39 * bar(); 40 * baz(); 41 * } 42 * --- 43 */ 44 otbs, 45 } 46 47 /** 48 * 49 */ 50 void format(Sink, T)(Sink sink, T node, bool useTabs = false, 51 IndentStyle style = IndentStyle.allman, uint indentWith = 4) 52 { 53 Formatter!Sink formatter = new Formatter!(Sink)(sink, useTabs, style, indentWith); 54 formatter.format(node); 55 } 56 57 /// 58 class Formatter(Sink) 59 { 60 /** 61 * Params: 62 * sink = the output range that the formatted source code is placed in 63 * useTabs = if true, tabs are used for indent levels instead of spaces 64 * style = the brace style 65 * indenteWidth = the number of spaces used for indentation if useTabs is false 66 */ 67 this(Sink sink, bool useTabs = false, IndentStyle style = IndentStyle.allman, uint indentWidth = 4) 68 { 69 this.sink = sink; 70 this.useTabs = useTabs; 71 this.style = style; 72 this.indentWidth = indentWidth; 73 } 74 75 /// 76 void format(const AddExpression addExpression) 77 { 78 debug(verbose) writeln("AddExpression"); 79 mixin(binary("addExpression")); 80 } 81 82 /// 83 void format(const AliasDeclaration aliasDeclaration, const Attribute[] attrs = null) 84 { 85 debug(verbose) writeln("AliasDeclaration"); 86 87 /** 88 LinkageAttribute linkageAttribute; 89 Type type; 90 Token name; 91 AliasInitializer[] initializers; 92 string comment; 93 **/ 94 95 with(aliasDeclaration) 96 { 97 newThing(What.other); 98 putComment(comment); 99 putAttrs(attrs); 100 put("alias "); 101 102 if (initializers.length) // alias ident = a, ident2 = b, etc 103 { 104 foreach(count, init; initializers) 105 { 106 if (count) 107 put(", "); 108 format(init); 109 } 110 } 111 else 112 { 113 foreach (storageClass; storageClasses) 114 { 115 format(storageClass); 116 space(); 117 } 118 119 if (type) 120 { 121 format(type); 122 space(); 123 } 124 format(identifierList); 125 } 126 put(";"); 127 } 128 } 129 130 void format(const AliasInitializer aliasInitializer) 131 { 132 debug(verbose) writeln("AliasInitializer"); 133 134 /** 135 Token name; 136 Type type; 137 **/ 138 139 with(aliasInitializer) 140 { 141 format(name); 142 put(" = "); 143 format(type); 144 } 145 } 146 147 void format(const AliasThisDeclaration decl, const Attribute[] attrs = null) 148 { 149 debug(verbose) writeln("AliasThisDeclaration"); 150 151 /** 152 Token identifier; 153 **/ 154 155 putAttrs(attrs); 156 put("alias "); 157 format(decl.identifier); 158 put(" this;"); 159 } 160 161 void format(const AlignAttribute alignAttribute) 162 { 163 debug(verbose) writeln("AlignAttribute"); 164 165 /** 166 Token intLiteral; 167 **/ 168 169 put("align"); 170 if (alignAttribute.intLiteral.text) 171 { 172 put("("); 173 format(alignAttribute.intLiteral); 174 put(")"); 175 } 176 } 177 178 void format(const AndAndExpression andAndExpression) 179 { 180 debug(verbose) writeln("AndAndExpression"); 181 182 with(andAndExpression) 183 { 184 format(left); 185 if (right) 186 { 187 put(" && "); 188 format(right); 189 } 190 } 191 } 192 193 void format(const AndExpression andExpression) 194 { 195 debug(verbose) writeln("AndExpression"); 196 197 with(andExpression) 198 { 199 format(left); 200 if (right) 201 { 202 put(" & "); 203 format(right); 204 } 205 } 206 } 207 208 void format(const ArgumentList argumentList) 209 { 210 debug(verbose) writeln("ArgumentList"); 211 212 foreach(count, arg; argumentList.items) 213 { 214 if (count) put(", "); 215 format(arg); 216 } 217 } 218 219 void format(const Arguments arguments) 220 { 221 debug(verbose) writeln("Arguments"); 222 223 put("("); 224 if (arguments.argumentList) format(arguments.argumentList); 225 put(")"); 226 } 227 228 void format(const ArrayInitializer arrayInitializer) 229 { 230 debug(verbose) writeln("ArrayInitializer"); 231 232 /** 233 ArrayMemberInitialization[] arrayMemberInitializations; 234 **/ 235 236 put("["); 237 foreach(count, init; arrayInitializer.arrayMemberInitializations) 238 { 239 format(init); 240 if (count < arrayInitializer.arrayMemberInitializations.length - 1) 241 put(", "); 242 } 243 put("]"); 244 } 245 246 void format(const ArrayLiteral arrayLiteral) 247 { 248 debug(verbose) writeln("ArrayLiteral"); 249 250 /** 251 ArgumentList argumentList; 252 **/ 253 put("["); 254 if (arrayLiteral.argumentList) 255 format(arrayLiteral.argumentList); 256 put("]"); 257 } 258 259 void format(const ArrayMemberInitialization arrayMemberInitialization) 260 { 261 debug(verbose) writeln("ArrayMemberInitialization"); 262 263 /** 264 AssignExpression assignExpression; 265 NonVoidInitializer nonVoidInitializer; 266 **/ 267 268 with(arrayMemberInitialization) 269 { 270 if (assignExpression) 271 { 272 format(assignExpression); 273 put(":"); 274 } 275 if (nonVoidInitializer) 276 format(nonVoidInitializer); 277 278 } 279 } 280 281 void format(const AsmAddExp asmAddExp) 282 { 283 assert(false); 284 } 285 286 void format(const AsmAndExp asmAndExp) 287 { 288 assert(false); 289 } 290 291 void format(const AsmBrExp asmBrExp) 292 { 293 assert(false); 294 } 295 296 void format(const AsmEqualExp asmEqualExp) 297 { 298 assert(false); 299 } 300 301 void format(const AsmExp asmExp) 302 { 303 assert(false); 304 } 305 306 void format(const AsmInstruction asmInstruction) 307 { 308 assert(false); 309 } 310 311 void format(const AsmLogAndExp asmLogAndExp) 312 { 313 assert(false); 314 } 315 316 void format(const AsmLogOrExp asmLogOrExp) 317 { 318 assert(false); 319 } 320 321 void format(const AsmMulExp asmMulExp) 322 { 323 assert(false); 324 } 325 326 void format(const AsmOrExp asmOrExp) 327 { 328 assert(false); 329 } 330 331 void format(const AsmPrimaryExp asmPrimaryExp) 332 { 333 assert(false); 334 } 335 336 void format(const AsmRelExp asmRelExp) 337 { 338 assert(false); 339 } 340 341 void format(const AsmShiftExp asmShiftExp) 342 { 343 assert(false); 344 } 345 346 void format(const AsmStatement asmStatement) 347 { 348 assert(false); 349 } 350 351 void format(const AsmTypePrefix asmTypePrefix) 352 { 353 assert(false); 354 } 355 356 void format(const AsmUnaExp asmUnaExp) 357 { 358 assert(false); 359 } 360 361 void format(const AsmXorExp asmXorExp) 362 { 363 assert(false); 364 } 365 366 void format(const AssertExpression assertExpression) 367 { 368 debug(verbose) writeln("AssertExpression"); 369 370 /** 371 AssignExpression assertion; 372 AssignExpression message; 373 **/ 374 375 with(assertExpression) 376 { 377 put("assert ("); 378 format(assertion); 379 if (message) 380 { 381 put(", "); 382 format(message); 383 } 384 put(")"); 385 } 386 } 387 388 void format(const AssignExpression assignExpression) 389 { 390 debug(verbose) writeln("AssignExpression"); 391 392 /** 393 ExpressionNode ternaryExpression; 394 ExpressionNode assignExpression; 395 IdType operator; 396 **/ 397 398 if (assignExpression.ternaryExpression) 399 format(assignExpression.ternaryExpression); 400 401 if(assignExpression.expression) 402 { 403 space(); 404 put(tokenRep(assignExpression.operator)); 405 space(); 406 format(assignExpression.expression); 407 } 408 } 409 410 void format(const AssocArrayLiteral assocArrayLiteral) 411 { 412 debug(verbose) writeln("AssocArrayLiteral"); 413 414 /** 415 KeyValuePairs keyValuePairs; 416 **/ 417 418 put("["); 419 format(assocArrayLiteral.keyValuePairs); 420 put("]"); 421 } 422 423 void format(const AtAttribute atAttribute) 424 { 425 debug(verbose) writeln("AtAttribute"); 426 427 /** 428 FunctionCallExpression functionCallExpression; 429 ArgumentList argumentList; 430 Token identifier; 431 **/ 432 433 with(atAttribute) 434 { 435 put("@"); 436 format(identifier); 437 if(argumentList) format(argumentList); 438 } 439 } 440 441 void format(const Attribute att) 442 { 443 debug(verbose) writeln("Attribute"); 444 445 /** 446 LinkageAttribute linkageAttribute; 447 AlignAttribute alignAttribute; 448 PragmaExpression pragmaExpression; 449 StorageClass storageClass; 450 IdType attribute; 451 **/ 452 453 with(att) 454 { 455 if (pragmaExpression) format(pragmaExpression); 456 if (attribute.type != tok!"") put(tokenRep(attribute.type)); 457 if (identifierChain) 458 { 459 put("("); 460 format(identifierChain); 461 put(")"); 462 } 463 if (deprecated_) format(deprecated_); 464 if (atAttribute) format(atAttribute); 465 if (linkageAttribute) format(linkageAttribute); 466 } 467 } 468 469 void format(const AttributeDeclaration decl, const Attribute[] attrs = null) 470 { 471 debug(verbose) writeln("AttributeDeclaration"); 472 473 auto cIndent = indentLevel; 474 outdent(); 475 newThing(What.attributeDecl); 476 putAttrs(attrs); 477 format(decl.attribute); 478 put(":"); 479 indentLevel = cIndent; 480 } 481 482 void format(const AutoDeclaration decl) 483 { 484 debug(verbose) writeln("AutoDeclaration"); 485 486 /** 487 Token[] identifiers; 488 Initializer[] initializers; 489 **/ 490 491 // zip doesn't work here, dmd 2.064.2 492 assert(decl.identifiers.length == decl.initializers.length); 493 foreach(i; 0..decl.identifiers.length) 494 { 495 if (i) put(", "); 496 format(decl.identifiers[i]); 497 put(" = "); 498 format(decl.initializers[i]); 499 } 500 } 501 502 void format(const BlockStatement blockStatement) 503 { 504 debug(verbose) writeln("BlockStatement"); 505 506 if (blockStatement.declarationsAndStatements is null) 507 { 508 space(); 509 put("{}"); 510 } 511 else 512 { 513 startBlock(); 514 format(blockStatement.declarationsAndStatements); 515 endBlock(); 516 } 517 } 518 519 void format(const BodyStatement bodyStatement) 520 { 521 debug(verbose) writeln("BodyStatement"); 522 523 newline(); 524 put("body"); 525 format(bodyStatement.blockStatement); 526 } 527 528 void format(const BreakStatement breakStatement) 529 { 530 debug(verbose) writeln("BreakStatement"); 531 532 put("break"); 533 if (breakStatement.label != tok!"") 534 { 535 space(); 536 format(breakStatement.label); 537 } 538 put(";"); 539 } 540 541 void format(const BaseClass baseClass) 542 { 543 debug(verbose) writeln("BaseClass"); 544 with(baseClass) 545 { 546 if (type2) format(type2); 547 } 548 } 549 550 void format(const BaseClassList baseClassList) 551 { 552 debug(verbose) writeln("BaseClassList"); 553 put(" : "); 554 foreach(count, item; baseClassList.items) 555 { 556 format(item); 557 if (count < baseClassList.items.length - 1) 558 put(", "); 559 } 560 } 561 562 void format(const CaseRangeStatement caseRangeStatement) 563 { 564 debug(verbose) writeln("CaseRangeStatement"); 565 566 /** 567 AssignExpression low; 568 AssignExpression high; 569 DeclarationsAndStatements declarationsAndStatements; 570 **/ 571 572 with(caseRangeStatement) 573 { 574 if (low) 575 { 576 put("case "); 577 format(low); 578 put(": .. "); 579 } 580 put("case "); 581 format(high); 582 put(":"); 583 584 formatCaseDecls(declarationsAndStatements); 585 } 586 } 587 588 void format(const CaseStatement caseStatement) 589 { 590 debug(verbose) writeln("CaseStatement"); 591 592 /** 593 ArgumentList argumentList; 594 DeclarationsAndStatements declarationsAndStatements; 595 **/ 596 597 with(caseStatement) 598 { 599 if (argumentList) 600 { 601 put("case "); 602 format(argumentList); 603 put(":"); 604 } 605 606 formatCaseDecls(declarationsAndStatements); 607 } 608 } 609 610 void format(const CastExpression castExpression) 611 { 612 debug(verbose) writeln("CastExpression"); 613 614 /** 615 Type type; 616 CastQualifier castQualifier; 617 UnaryExpression unaryExpression; 618 **/ 619 620 with(castExpression) 621 { 622 put("cast("); 623 if (castQualifier) 624 { 625 format(castQualifier); 626 space(); 627 } 628 if (type) format(type); 629 put(")"); 630 if (unaryExpression) format(unaryExpression); 631 } 632 } 633 634 void format(const CastQualifier qual) 635 { 636 debug(verbose) writeln("CastQualifier"); 637 638 /** 639 Token first; 640 Token second; 641 **/ 642 643 format(qual.first); 644 if (qual.second != tok!"") 645 { 646 space(); 647 format(qual.second); 648 } 649 } 650 651 void format(const Catch catch_) 652 { 653 debug(verbose) writeln("Catch"); 654 655 /** 656 Type type; 657 Token identifier; 658 DeclarationOrStatement declarationOrStatement; 659 **/ 660 661 with(catch_) 662 { 663 newThing(What.catch_); 664 put("catch("); 665 format(type); 666 if (identifier != tok!"") 667 { 668 space(); 669 format(identifier); 670 } 671 put(")"); 672 if (declarationOrStatement) maybeIndent(declarationOrStatement); 673 } 674 } 675 676 void format(const Catches catches) 677 { 678 debug(verbose) writeln("Catches"); 679 680 /** 681 Catch[] catches; 682 LastCatch lastCatch; 683 **/ 684 685 foreach(c; catches.catches) 686 format(c); 687 if (catches.lastCatch) 688 format(catches.lastCatch); 689 } 690 691 void format(const ClassDeclaration decl, const Attribute[] attrs = null) 692 { 693 debug(verbose) writeln("ClassDeclaration"); 694 695 /** 696 Token name; 697 TemplateParameters templateParameters; 698 Constraint constraint; 699 BaseClassList baseClassList; 700 StructBody structBody; 701 string comment; 702 **/ 703 704 newThing(What.aggregateDecl); 705 putComment(decl.comment); 706 putAttrs(attrs); 707 708 put("class "); 709 format(decl.name); 710 711 if (decl.templateParameters) 712 format(decl.templateParameters); 713 714 if (decl.constraint) 715 { 716 space(); 717 format(decl.constraint); 718 } 719 720 if (decl.baseClassList) 721 { 722 format(decl.baseClassList); 723 } 724 725 format(decl.structBody); 726 } 727 728 void format(const CmpExpression cmpExpression) 729 { 730 debug(verbose) writeln("CmpExpression"); 731 732 /** 733 ExpressionNode shiftExpression; 734 ExpressionNode equalExpression; 735 ExpressionNode identityExpression; 736 ExpressionNode relExpression; 737 ExpressionNode inExpression; 738 **/ 739 740 with(cmpExpression) 741 { 742 if (shiftExpression) format(shiftExpression); 743 else if (equalExpression) format(equalExpression); 744 else if (identityExpression) format(identityExpression); 745 else if (relExpression) format(relExpression); 746 else if (inExpression) format(inExpression); 747 } 748 } 749 750 void format(const CompileCondition compileCondition) 751 { 752 debug(verbose) writeln("CompileCondition"); 753 754 /** 755 VersionCondition versionCondition; 756 DebugCondition debugCondition; 757 StaticIfCondition staticIfCondition; 758 **/ 759 760 with(compileCondition) 761 { 762 if (versionCondition) format(versionCondition); 763 else if (debugCondition) format(debugCondition); 764 else if (staticIfCondition) format(staticIfCondition); 765 } 766 } 767 768 void format(const ConditionalDeclaration decl, const Attribute[] attrs = null) 769 { 770 debug(verbose) writeln("ConditionalDeclaration"); 771 772 /** 773 CompileCondition compileCondition; 774 Declaration[] trueDeclarations; 775 Declaration[] falseDeclaration; 776 **/ 777 778 newThing(What.conditionalDecl); 779 putAttrs(attrs); 780 format(decl.compileCondition); 781 782 if (decl.trueDeclarations.length > 1) 783 { 784 startBlock(); 785 foreach (d; decl.trueDeclarations) 786 format(d); 787 endBlock(); 788 } 789 else if (decl.trueDeclarations.length == 0) 790 maybeIndent(decl.trueDeclarations[0]); 791 else 792 put("{}"); 793 794 if (decl.falseDeclarations.length > 0) 795 put("else"); 796 797 if (decl.falseDeclarations.length > 1) 798 { 799 startBlock(); 800 foreach (d; decl.falseDeclarations) 801 format(d); 802 endBlock(); 803 } 804 else if (decl.falseDeclarations.length == 0) 805 maybeIndent(decl.falseDeclarations[0]); 806 else 807 put("{}"); 808 } 809 810 void format(const ConditionalStatement stmnt) 811 { 812 debug(verbose) writeln("ConditionalStatement"); 813 814 /** 815 CompileCondition compileCondition; 816 DeclarationOrStatement trueStatement; 817 DeclarationOrStatement falseStatement; 818 **/ 819 820 newThing(What.other); 821 if (stmnt.compileCondition) 822 format(stmnt.compileCondition); 823 824 if (stmnt.trueStatement) 825 maybeIndent(stmnt.trueStatement); 826 827 if (stmnt.falseStatement) 828 { 829 newThing(What.else_); 830 put("else "); 831 832 // else if... 833 if (stmnt.falseStatement.statement && 834 stmnt.falseStatement.statement.statementNoCaseNoDefault && 835 stmnt.falseStatement.statement.statementNoCaseNoDefault.conditionalStatement) 836 { 837 format(stmnt.falseStatement.statement.statementNoCaseNoDefault.conditionalStatement); 838 return; 839 } 840 841 maybeIndent(stmnt.falseStatement); 842 } 843 } 844 845 void format(const Constraint constraint) 846 { 847 debug(verbose) writeln("Constraint"); 848 849 if (constraint.expression) 850 { 851 indent(); 852 newline(); 853 put("if("); 854 format(constraint.expression); 855 put(")"); 856 outdent(); 857 } 858 } 859 860 void format(const Constructor constructor, const Attribute[] attrs = null) 861 { 862 debug(verbose) writeln("Constructor"); 863 864 /** 865 Parameters parameters; 866 FunctionBody functionBody; 867 Constraint constraint; 868 MemberFunctionAttribute[] memberFunctionAttributes; 869 TemplateParameters templateParameters; 870 size_t location; 871 string comment; 872 **/ 873 874 newThing(What.functionDecl); 875 putComment(constructor.comment); 876 putAttrs(attrs); 877 878 put("this"); 879 880 if (constructor.templateParameters) 881 format(constructor.templateParameters); 882 883 if (constructor.parameters) 884 format(constructor.parameters); 885 886 foreach(att; constructor.memberFunctionAttributes) 887 { 888 space(); 889 format(att); 890 } 891 892 if (constructor.constraint) 893 { 894 space(); 895 format(constructor.constraint); 896 } 897 898 if (constructor.functionBody) 899 format(constructor.functionBody); 900 else 901 put(";"); 902 } 903 904 void format(const ContinueStatement continueStatement) 905 { 906 debug(verbose) writeln("ContinueStatement"); 907 908 put("continue"); 909 if (continueStatement.label != tok!"") 910 { 911 space(); 912 format(continueStatement.label); 913 } 914 put(";"); 915 } 916 917 void format(const DebugCondition debugCondition) 918 { 919 debug(verbose) writeln("DebugCondition"); 920 921 put("debug"); 922 if (debugCondition.identifierOrInteger != tok!"") 923 { 924 put("("); 925 format(debugCondition.identifierOrInteger); 926 put(")"); 927 } 928 } 929 930 void format(const DebugSpecification debugSpecification) 931 { 932 debug(verbose) writeln("DebugSpecification"); 933 934 newThing(What.other); 935 put("debug = "); 936 format(debugSpecification.identifierOrInteger); 937 put(";"); 938 } 939 940 void format(const Declaration declaration) 941 { 942 debug(verbose) writeln("Declaration"); 943 944 with(declaration) 945 { 946 string mix(string[] s) { 947 string r; 948 foreach(c, d; s) 949 r ~= (c > 0 ? "else " : "") ~ "if (" ~ d ~ ") { format(" ~ d ~ ", attributes); }"; 950 return r; 951 } 952 953 mixin(mix(possibleDeclarations)); 954 955 if (declarations.length) 956 { 957 putAttrs(attributes); 958 startBlock(); 959 foreach(d; declarations) 960 format(d); 961 endBlock(); 962 } 963 } 964 } 965 966 void format(const DeclarationOrStatement declarationsOrStatement) 967 { 968 debug(verbose) writeln("DeclarationOrStatement"); 969 970 with(declarationsOrStatement) 971 declaration !is null ? format(declaration) : format(statement); 972 } 973 974 void format(const DeclarationsAndStatements declarationsAndStatements) 975 { 976 debug(verbose) writeln("DeclarationsAndStatements"); 977 978 foreach(ds; declarationsAndStatements.declarationsAndStatements) 979 format(ds); 980 } 981 982 void format(const Declarator declarator) 983 { 984 debug(verbose) writeln("Declarator"); 985 986 /** 987 Token name; 988 Initializer initializer; 989 **/ 990 991 format(declarator.name); 992 993 foreach(suffix; declarator.cstyle) 994 format(suffix); 995 996 if (declarator.templateParameters) 997 format(declarator.templateParameters); 998 999 if (declarator.initializer) 1000 { 1001 put(" = "); 1002 format(declarator.initializer); 1003 } 1004 } 1005 1006 void format(const DefaultStatement defaultStatement) 1007 { 1008 debug(verbose) writeln("DefaultStatement"); 1009 1010 /** 1011 DeclarationsAndStatements declarationsAndStatements; 1012 **/ 1013 1014 put("default:"); 1015 formatCaseDecls(defaultStatement.declarationsAndStatements); 1016 } 1017 1018 void format(const DeleteExpression deleteExpression) 1019 { 1020 debug(verbose) writeln("DeleteExpression"); 1021 1022 put("delete "); 1023 format(deleteExpression.unaryExpression); 1024 } 1025 1026 void format(const DeleteStatement deleteStatement) 1027 { 1028 debug(verbose) writeln("DeleteStatement"); 1029 1030 format(deleteStatement.deleteExpression); 1031 put(";"); 1032 } 1033 1034 void format(const Deprecated deprecated_) 1035 { 1036 debug (verbose) 1037 writeln("Deprecated"); 1038 put("deprecated"); 1039 if (deprecated_.assignExpression !is null) 1040 { 1041 put("("); 1042 format(deprecated_.assignExpression); 1043 put(")"); 1044 } 1045 } 1046 1047 void format(const Destructor destructor, const Attribute[] attrs = null) 1048 { 1049 debug(verbose) writeln("Destructor"); 1050 1051 /** 1052 FunctionBody functionBody; 1053 **/ 1054 1055 newThing(What.functionDecl); 1056 putAttrs(attrs); 1057 put("~this()"); 1058 1059 if (destructor.functionBody) 1060 format(destructor.functionBody); 1061 else 1062 put(";"); 1063 } 1064 1065 void format(const DoStatement doStatement) 1066 { 1067 debug(verbose) writeln("DoStatement"); 1068 1069 /** 1070 StatementNoCaseNoDefault statementNoCaseNoDefault; 1071 Expression expression; 1072 **/ 1073 1074 with(doStatement) 1075 { 1076 newThing(What.other); 1077 put("do"); 1078 if (statementNoCaseNoDefault) format(statementNoCaseNoDefault); 1079 space(); 1080 put("while ("); 1081 format(expression); 1082 put(");"); 1083 } 1084 } 1085 1086 void format(const EnumBody enumBody) 1087 { 1088 debug(verbose) writeln("EnumBody"); 1089 1090 newline(); 1091 startBlock(); 1092 foreach(count, member; enumBody.enumMembers) 1093 { 1094 format(member); 1095 1096 if (count < enumBody.enumMembers.length - 1) 1097 put(","); 1098 1099 if (member.comment.length) 1100 { 1101 space(); 1102 put(member.comment); 1103 } 1104 } 1105 endBlock(); 1106 } 1107 1108 void format(const EnumDeclaration enumDeclaration, const Attribute[] attrs = null) 1109 { 1110 debug(verbose) writeln("EnumDeclaration"); 1111 1112 /** 1113 Token name; 1114 Type type; 1115 EnumBody enumBody; 1116 string comment; 1117 **/ 1118 1119 with(enumDeclaration) 1120 { 1121 newThing(What.aggregateDecl); 1122 putComment(comment); 1123 putAttrs(attrs); 1124 put("enum "); 1125 if (name != tok!"") 1126 { 1127 format(name); 1128 space(); 1129 } 1130 if (type) 1131 { 1132 put(": "); 1133 format(type); 1134 space(); 1135 } 1136 if (enumBody) format(enumBody); 1137 } 1138 } 1139 1140 void format(const EnumMember enumMember) 1141 { 1142 debug(verbose) writeln("EnumMember"); 1143 1144 /** 1145 Token name; 1146 Type type; 1147 AssignExpression assignExpression; 1148 string comment; 1149 **/ 1150 1151 with(enumMember) 1152 { 1153 newline(); 1154 if (type) format(type); 1155 format(name); 1156 if (assignExpression) 1157 { 1158 put(" = "); 1159 format(assignExpression); 1160 } 1161 } 1162 } 1163 1164 void format(const EponymousTemplateDeclaration decl) 1165 { 1166 debug(verbose) writeln("EponymousTemplateDeclaration"); 1167 1168 /** 1169 Token name; 1170 TemplateParameters templateParameters; 1171 AssignExpression assignExpression; 1172 **/ 1173 1174 put("enum "); 1175 put(tokenRep(decl.name)); 1176 if (decl.templateParameters) 1177 format(decl.templateParameters); 1178 if (decl.assignExpression) 1179 { 1180 put(" = "); 1181 format(decl.assignExpression); 1182 } 1183 put(";"); 1184 } 1185 1186 void format(const EqualExpression equalExpression) 1187 { 1188 debug(verbose) writeln("EqualExpression"); 1189 1190 mixin(binary("equalExpression")); 1191 } 1192 1193 void format(const Expression expression) 1194 { 1195 debug(verbose) writeln("Expression"); 1196 1197 foreach(count, item; expression.items) 1198 { 1199 if (count) 1200 put(", "); 1201 format(item); 1202 } 1203 } 1204 1205 void format(const ExpressionNode n) 1206 { 1207 debug(verbose) writeln("ExpressionNode"); 1208 1209 if (cast(AddExpression) n) format(cast(AddExpression) n); 1210 else if (cast(AndAndExpression) n) format(cast(AndAndExpression) n); 1211 else if (cast(AndExpression) n) format(cast(AndExpression) n); 1212 else if (cast(AsmAddExp) n) format(cast(AsmAddExp) n); 1213 else if (cast(AsmAndExp) n) format(cast(AsmAndExp) n); 1214 else if (cast(AsmEqualExp) n) format(cast(AsmEqualExp) n); 1215 else if (cast(AsmLogAndExp) n) format(cast(AsmLogAndExp) n); 1216 else if (cast(AsmLogOrExp) n) format(cast(AsmLogOrExp) n); 1217 else if (cast(AsmMulExp) n) format(cast(AsmMulExp) n); 1218 else if (cast(AsmOrExp) n) format(cast(AsmOrExp) n); 1219 else if (cast(AsmRelExp) n) format(cast(AsmRelExp) n); 1220 else if (cast(AsmShiftExp) n) format(cast(AsmShiftExp) n); 1221 else if (cast(AssertExpression) n) format(cast(AssertExpression) n); 1222 else if (cast(AssignExpression) n) format(cast(AssignExpression) n); 1223 else if (cast(CmpExpression) n) format(cast(CmpExpression) n); 1224 else if (cast(DeleteExpression) n) format(cast(DeleteExpression) n); 1225 else if (cast(EqualExpression) n) format(cast(EqualExpression) n); 1226 else if (cast(Expression) n) format(cast(Expression) n); 1227 else if (cast(FunctionCallExpression) n) format(cast(FunctionCallExpression) n); 1228 else if (cast(FunctionLiteralExpression) n) format(cast(FunctionLiteralExpression) n); 1229 else if (cast(IdentityExpression) n) format(cast(IdentityExpression) n); 1230 else if (cast(ImportExpression) n) format(cast(ImportExpression) n); 1231 else if (cast(IndexExpression) n) format(cast(IndexExpression) n); 1232 else if (cast(InExpression) n) format(cast(InExpression) n); 1233 else if (cast(IsExpression) n) format(cast(IsExpression) n); 1234 else if (cast(MixinExpression) n) format(cast(MixinExpression) n); 1235 else if (cast(MulExpression) n) format(cast(MulExpression) n); 1236 else if (cast(NewAnonClassExpression) n) format(cast(NewAnonClassExpression) n); 1237 else if (cast(NewExpression) n) format(cast(NewExpression) n); 1238 else if (cast(OrExpression) n) format(cast(OrExpression) n); 1239 else if (cast(OrOrExpression) n) format(cast(OrOrExpression) n); 1240 else if (cast(PowExpression) n) format(cast(PowExpression) n); 1241 else if (cast(PragmaExpression) n) format(cast(PragmaExpression) n); 1242 else if (cast(PrimaryExpression) n) format(cast(PrimaryExpression) n); 1243 else if (cast(RelExpression) n) format(cast(RelExpression) n); 1244 else if (cast(ShiftExpression) n) format(cast(ShiftExpression) n); 1245 else if (cast(TemplateMixinExpression) n) format(cast(TemplateMixinExpression) n); 1246 else if (cast(TernaryExpression) n) format(cast(TernaryExpression) n); 1247 else if (cast(TraitsExpression) n) format(cast(TraitsExpression) n); 1248 else if (cast(TypeidExpression) n) format(cast(TypeidExpression) n); 1249 else if (cast(TypeofExpression) n) format(cast(TypeofExpression) n); 1250 else if (cast(UnaryExpression) n) format(cast(UnaryExpression) n); 1251 else if (cast(XorExpression) n) format(cast(XorExpression) n); 1252 } 1253 1254 void format(const ExpressionStatement expressionStatement) 1255 { 1256 debug(verbose) writeln("ExpressionStatement"); 1257 1258 if (expressionStatement.expression) 1259 format(expressionStatement.expression); 1260 put(";"); 1261 } 1262 1263 void format(const FinalSwitchStatement finalSwitchStatement) 1264 { 1265 debug(verbose) writeln("FinalSwitchStatement"); 1266 1267 format(finalSwitchStatement.switchStatement, true); 1268 } 1269 1270 void format(const Finally finally_) 1271 { 1272 debug(verbose) writeln("Finally"); 1273 1274 put("finally"); 1275 format(finally_.declarationOrStatement); 1276 } 1277 1278 void format(const ForStatement forStatement) 1279 { 1280 debug(verbose) writeln("ForStatement"); 1281 1282 /** 1283 DeclarationOrStatement initialization; 1284 ExpressionStatement test; 1285 Expression increment; 1286 DeclarationOrStatement declarationOrStatement; 1287 **/ 1288 1289 with(forStatement) 1290 { 1291 newThing(What.other); 1292 put("for ("); 1293 if (initialization) format(initialization); 1294 else put(";"); 1295 space(); 1296 if (test) format(test); 1297 put(";"); 1298 space(); 1299 if (increment) format(increment); 1300 put(")"); 1301 1302 if (declarationOrStatement) maybeIndent(declarationOrStatement); 1303 } 1304 } 1305 1306 void format(const ForeachStatement foreachStatement) 1307 { 1308 debug(verbose) writeln("ForeachStatement"); 1309 1310 /** 1311 IdType type; 1312 ForeachTypeList foreachTypeList; 1313 ForeachType foreachType; 1314 Expression low; 1315 Expression high; 1316 DeclarationOrStatement declarationOrStatement; 1317 size_t startIndex; 1318 **/ 1319 1320 with(foreachStatement) 1321 { 1322 newThing(What.loop); 1323 if (type) put(tokenRep(type)); 1324 else assert(false); 1325 1326 put(" ("); 1327 if (foreachTypeList) format(foreachTypeList); 1328 else if (foreachType) format(foreachType); 1329 1330 put("; "); 1331 1332 if (low) format(low); 1333 if (high) 1334 { 1335 put(".."); 1336 format(high); 1337 } 1338 put(")"); 1339 format(declarationOrStatement); 1340 } 1341 } 1342 1343 void format(const ForeachType foreachType) 1344 { 1345 debug(verbose) writeln("ForeachType"); 1346 1347 /** 1348 IdType[] typeConstructors; 1349 Type type; 1350 Token identifier; 1351 **/ 1352 1353 with(foreachType) 1354 { 1355 foreach(tp; typeConstructors) 1356 { 1357 if (tp) put(tokenRep(tp)); 1358 space(); 1359 } 1360 if (type) 1361 { 1362 format(type); 1363 space(); 1364 } 1365 format(identifier); 1366 } 1367 } 1368 1369 void format(const ForeachTypeList foreachTypeList) 1370 { 1371 debug(verbose) writeln("ForeachTypeList"); 1372 1373 /** 1374 ForeachType[] items; 1375 **/ 1376 1377 foreach(count, item; foreachTypeList.items) 1378 { 1379 format(item); 1380 if (count < foreachTypeList.items.length - 1) 1381 put(", "); 1382 } 1383 } 1384 1385 void format(const FunctionAttribute functionAttribute) 1386 { 1387 debug(verbose) writeln("FunctionAttribute"); 1388 1389 /** 1390 Token token; 1391 AtAttribute atAttribute; 1392 **/ 1393 1394 with(functionAttribute) 1395 { 1396 if (token != tok!"") 1397 { 1398 format(token); 1399 space(); 1400 } 1401 if (atAttribute) format(atAttribute); 1402 } 1403 } 1404 1405 void format(const FunctionBody functionBody) 1406 { 1407 debug(verbose) writeln("FunctionBody"); 1408 1409 with(functionBody) 1410 { 1411 if (blockStatement) 1412 { 1413 format(blockStatement); 1414 return; 1415 } 1416 if (inStatement) 1417 format(inStatement); 1418 if (outStatement) 1419 format(outStatement); 1420 if (bodyStatement) 1421 format(bodyStatement); 1422 } 1423 } 1424 1425 void format(const FunctionCallExpression functionCallExpression) 1426 { 1427 debug(verbose) writeln("FunctionCallExpression"); 1428 1429 /** 1430 Type type; 1431 UnaryExpression unaryExpression; 1432 TemplateArguments templateArguments; 1433 Arguments arguments; 1434 **/ 1435 1436 with(functionCallExpression) 1437 { 1438 if (type) format(type); 1439 if (unaryExpression) format(unaryExpression); 1440 if (templateArguments) format(templateArguments); 1441 if (arguments) format(arguments); 1442 } 1443 } 1444 1445 void format(const FunctionDeclaration decl, const Attribute[] attrs = null) 1446 { 1447 debug(verbose) writeln("FunctionDeclaration"); 1448 1449 /** 1450 bool hasAuto; 1451 bool hasRef; 1452 **/ 1453 1454 newThing(What.functionDecl); 1455 putComment(decl.comment); 1456 putAttrs(attrs); 1457 1458 foreach (sc; decl.storageClasses) 1459 format(sc); 1460 1461 if (decl.returnType) 1462 format(decl.returnType); 1463 1464 space(); 1465 format(decl.name); 1466 1467 if (decl.templateParameters) 1468 format(decl.templateParameters); 1469 if (decl.parameters) 1470 format(decl.parameters); 1471 foreach(attr; decl.memberFunctionAttributes) 1472 { 1473 space(); 1474 format(attr); 1475 } 1476 if (decl.constraint) 1477 { 1478 space(); 1479 format(decl.constraint); 1480 } 1481 1482 if (decl.functionBody) 1483 format(decl.functionBody); 1484 else 1485 put(";"); 1486 } 1487 1488 void format(const FunctionLiteralExpression functionLiteralExpression) 1489 { 1490 debug(verbose) writeln("FunctionLiteralExpression"); 1491 1492 with(functionLiteralExpression) 1493 { 1494 put(tokenRep(functionOrDelegate)); 1495 1496 space(); 1497 if (returnType) format(returnType); 1498 if (parameters) format(parameters); 1499 1500 foreach(att; memberFunctionAttributes) 1501 { 1502 space(); 1503 format(att); 1504 } 1505 1506 ignoreNewlines = true; 1507 if (functionBody) 1508 format(functionBody); 1509 else 1510 { 1511 put(" => "); 1512 format(assignExpression); 1513 } 1514 ignoreNewlines = false; 1515 } 1516 } 1517 1518 void format(const GotoStatement gotoStatement) 1519 { 1520 debug(verbose) writeln("GotoStatement"); 1521 1522 put("goto "); 1523 gotoStatement.label != tok!"" ? 1524 put(tokenRep(gotoStatement.label)) : 1525 format(gotoStatement.expression); 1526 put(";"); 1527 } 1528 1529 void format(const IdentifierChain identifierChain) 1530 { 1531 debug(verbose) writeln("IdentifierChain"); 1532 1533 foreach(count, ident; identifierChain.identifiers) 1534 { 1535 if (count) put("."); 1536 put(ident.text); 1537 } 1538 } 1539 1540 void format(const IdentifierList identifierList) 1541 { 1542 debug(verbose) writeln("IdentifierList"); 1543 foreach(count, ident; identifierList.identifiers) 1544 { 1545 if (count) put(", "); 1546 put(ident.text); 1547 } 1548 } 1549 1550 void format(const IdentifierOrTemplateChain identifierOrTemplateChain) 1551 { 1552 debug(verbose) writeln("IdentifierOrTemplateChain"); 1553 1554 with(identifierOrTemplateChain) 1555 { 1556 foreach(count, ident; identifiersOrTemplateInstances) 1557 { 1558 if (count) put("."); 1559 format(ident); 1560 } 1561 } 1562 } 1563 1564 void format(const IdentifierOrTemplateInstance identifierOrTemplateInstance) 1565 { 1566 debug(verbose) writeln("IdentifierOrTemplateInstance"); 1567 1568 with(identifierOrTemplateInstance) 1569 { 1570 format(identifier); 1571 if (templateInstance) 1572 format(templateInstance); 1573 } 1574 } 1575 1576 void format(const IdentityExpression identityExpression) 1577 { 1578 debug(verbose) writeln("IdentityExpression"); 1579 1580 with(identityExpression) 1581 { 1582 if (left) format(left); 1583 put(negated ? " !is " : " is "); 1584 if (right) format(right); 1585 } 1586 } 1587 1588 void format(const IfStatement ifStatement) 1589 { 1590 debug(verbose) writeln("IfStatement"); 1591 1592 /** 1593 Token identifier; 1594 Type type; 1595 Expression expression; 1596 DeclarationOrStatement thenStatement; 1597 DeclarationOrStatement elseStatement; 1598 **/ 1599 1600 with(ifStatement) 1601 { 1602 bool isAuto = identifier != tok!"" && !type; 1603 bool isAssign = isAuto || type; 1604 1605 put("if ("); 1606 1607 if (isAuto) put("auto "); 1608 if (type) 1609 { 1610 format(type); 1611 space(); 1612 } 1613 if (identifier != tok!"") 1614 { 1615 format(identifier); 1616 space(); 1617 } 1618 if (isAssign) put("= "); 1619 if (expression) format(expression); 1620 put(")"); 1621 1622 if (thenStatement) 1623 maybeIndent(thenStatement); 1624 1625 if (elseStatement) 1626 { 1627 newThing(What.else_); 1628 put("else "); 1629 1630 if (elseStatement.statement && 1631 elseStatement.statement.statementNoCaseNoDefault && 1632 elseStatement.statement.statementNoCaseNoDefault.ifStatement) 1633 { 1634 // this is to stop automatic newlineIndent 1635 format(elseStatement.statement.statementNoCaseNoDefault.ifStatement); 1636 } 1637 else 1638 maybeIndent(elseStatement); 1639 } 1640 1641 } 1642 } 1643 1644 void format(const ImportBind importBind) 1645 { 1646 debug(verbose) writeln("ImportBind"); 1647 1648 format(importBind.left); 1649 if (importBind.right != tok!"") 1650 { 1651 put(" = "); 1652 format(importBind.right); 1653 } 1654 } 1655 1656 void format(const ImportBindings importBindings) 1657 { 1658 debug(verbose) writeln("ImportBindings"); 1659 1660 /** 1661 SingleImport singleImport; 1662 ImportBind[] importBinds; 1663 **/ 1664 1665 with(importBindings) 1666 { 1667 format(singleImport); 1668 put(" : "); 1669 foreach(count, bind; importBinds) 1670 { 1671 if (count) put(", "); 1672 format(bind); 1673 } 1674 } 1675 } 1676 1677 void format(const ImportDeclaration importDeclaration, const Attribute[] attrs = null) 1678 { 1679 debug(verbose) writeln("ImportDeclaration"); 1680 1681 /** 1682 SingleImport[] singleImports; 1683 ImportBindings importBindings; 1684 **/ 1685 1686 with(importDeclaration) 1687 { 1688 newThing(What.importDecl); 1689 putAttrs(attrs); 1690 put("import "); 1691 1692 if (singleImports.length == 1) 1693 { 1694 format(singleImports[0]); 1695 } 1696 else if (singleImports.length > 1) 1697 { 1698 indent(); 1699 newlineIndent(); 1700 foreach(count, imp; singleImports) 1701 { 1702 format(imp); 1703 if (count < singleImports.length - 1) 1704 { 1705 put(", "); 1706 newlineIndent(); 1707 } 1708 } 1709 outdent(); 1710 } 1711 1712 if (importBindings) 1713 { 1714 if (singleImports.length) 1715 put(", "); 1716 format(importBindings); 1717 } 1718 put(";"); 1719 } 1720 } 1721 1722 void format(const ImportExpression importExpression) 1723 { 1724 debug(verbose) writeln("ImportExpression"); 1725 1726 put("import ("); 1727 format(importExpression.assignExpression); 1728 put(");"); 1729 } 1730 1731 void format(const Index index) 1732 { 1733 format(index.low); 1734 if (index.high !is null) 1735 { 1736 put(" .. "); 1737 format(index.high); 1738 } 1739 } 1740 1741 void format(const IndexExpression indexExpression) 1742 { 1743 debug(verbose) writeln("IndexExpression"); 1744 1745 /** 1746 UnaryExpression unaryExpression; 1747 ArgumentList argumentList; 1748 **/ 1749 1750 with(indexExpression) 1751 { 1752 format(indexExpression.unaryExpression); 1753 put("["); 1754 foreach (i, index; indexes) 1755 { 1756 if (i != 0) 1757 put(", "); 1758 format(index); 1759 } 1760 put("]"); 1761 } 1762 } 1763 1764 void format(const InExpression inExpression) 1765 { 1766 debug(verbose) writeln("InExpression"); 1767 1768 with(inExpression) 1769 { 1770 if (left) format(left); 1771 put(negated ? " !in " : " in "); 1772 if (right) format(right); 1773 } 1774 } 1775 1776 void format(const InStatement inStatement) 1777 { 1778 debug(verbose) writeln("InStatement"); 1779 put("in"); 1780 format(inStatement.blockStatement); 1781 } 1782 1783 void format(const Initialize initialize) 1784 { 1785 debug(verbose) writeln("Initialize"); 1786 assert(false); 1787 } 1788 1789 void format(const Initializer initializer) 1790 { 1791 debug(verbose) writeln("Initializer"); 1792 1793 initializer.nonVoidInitializer ? format(initializer.nonVoidInitializer) : put("void"); 1794 } 1795 1796 void format(const InterfaceDeclaration interfaceDeclaration, const Attribute[] attrs = null) 1797 { 1798 debug(verbose) writeln("InterfaceDeclaration"); 1799 1800 /** 1801 Token name; 1802 TemplateParameters templateParameters; 1803 Constraint constraint; 1804 BaseClassList baseClassList; 1805 StructBody structBody; 1806 string comment; 1807 **/ 1808 1809 with(interfaceDeclaration) 1810 { 1811 newThing(What.aggregateDecl); 1812 putComment(comment); 1813 putAttrs(attrs); 1814 1815 put("interface "); 1816 format(name); 1817 if (templateParameters) format(templateParameters); 1818 if (constraint) 1819 { 1820 space(); 1821 format(constraint); 1822 } 1823 if (baseClassList) 1824 { 1825 format(baseClassList); 1826 } 1827 1828 if (structBody) 1829 format(structBody); 1830 else 1831 put(";"); 1832 } 1833 } 1834 1835 void format(const Invariant invariant_, const Attribute[] attrs = null) 1836 { 1837 debug(verbose) writeln("Invariant"); 1838 1839 /** 1840 BlockStatement blockStatement; 1841 string comment; 1842 **/ 1843 1844 putComment(invariant_.comment); 1845 putAttrs(attrs); 1846 put("invariant()"); 1847 format(invariant_.blockStatement); 1848 } 1849 1850 void format(const IsExpression isExpression) 1851 { 1852 debug(verbose) writeln("IsExpression"); 1853 1854 /** 1855 Type type; 1856 Token identifier; 1857 TypeSpecialization typeSpecialization; 1858 TemplateParameterList templateParameterList; 1859 IdType equalsOrColon; 1860 **/ 1861 1862 with(isExpression) 1863 { 1864 put("is("); 1865 if (type) format(type); 1866 if (identifier != tok!"") 1867 { 1868 space(); 1869 format(identifier); 1870 } 1871 1872 if (equalsOrColon) 1873 { 1874 space(); 1875 put(tokenRep(equalsOrColon)); 1876 space(); 1877 } 1878 1879 if (typeSpecialization) format(typeSpecialization); 1880 if (templateParameterList) 1881 { 1882 put(", "); 1883 format(templateParameterList); 1884 } 1885 put(")"); 1886 } 1887 } 1888 1889 void format(const KeyValuePair keyValuePair) 1890 { 1891 debug(verbose) writeln("KeyValuePair"); 1892 1893 /** 1894 AssignExpression key; 1895 AssignExpression value; 1896 **/ 1897 1898 format(keyValuePair.key); 1899 put(":"); 1900 format(keyValuePair.value); 1901 } 1902 1903 void format(const KeyValuePairs keyValuePairs) 1904 { 1905 debug(verbose) writeln("KeyValuePairs"); 1906 1907 /** 1908 KeyValuePair[] keyValuePairs; 1909 **/ 1910 1911 foreach(count, pair; keyValuePairs.keyValuePairs) 1912 { 1913 format(pair); 1914 if (count + 1 < keyValuePairs.keyValuePairs.length) 1915 put(", "); 1916 } 1917 } 1918 1919 void format(const LabeledStatement stmt) 1920 { 1921 debug(verbose) writeln("LabeledStatement"); 1922 1923 /** 1924 Token identifier; 1925 DeclarationOrStatement declarationOrStatement; 1926 **/ 1927 1928 format(stmt.identifier); 1929 put(":"); 1930 if (stmt.declarationOrStatement) 1931 format(stmt.declarationOrStatement); 1932 } 1933 1934 void format(const LastCatch lastCatch) 1935 { 1936 debug(verbose) writeln("LastCatch"); 1937 1938 put("catch"); 1939 format(lastCatch.statementNoCaseNoDefault); 1940 } 1941 1942 void format(const LinkageAttribute linkageAttribute) 1943 { 1944 debug(verbose) writeln("LinkageAttribute"); 1945 1946 /** 1947 Token identifier; 1948 bool hasPlusPlus; 1949 IdentifierChain identifierChain; 1950 **/ 1951 1952 put("extern ("); 1953 format(linkageAttribute.identifier); 1954 if (linkageAttribute.hasPlusPlus) 1955 { 1956 put("++"); 1957 if (linkageAttribute.identifierChain && linkageAttribute.identifierChain.identifiers.length > 0) 1958 { 1959 put(", "); 1960 format(linkageAttribute.identifierChain); 1961 } 1962 } 1963 put(")"); 1964 } 1965 1966 void format(const MemberFunctionAttribute memberFunctionAttribute) 1967 { 1968 debug(verbose) writeln("MemberFunctionAttribute"); 1969 1970 /** 1971 IdType tokenType; 1972 AtAttribute atAttribute; 1973 **/ 1974 1975 with(memberFunctionAttribute) 1976 { 1977 if (tokenType) put(tokenRep(tokenType)); 1978 else format(atAttribute); 1979 } 1980 } 1981 1982 void format(const MixinDeclaration mixinDeclaration, const Attribute[] attrs = null) 1983 { 1984 debug(verbose) writeln("MixinDeclaration"); 1985 1986 /** 1987 MixinExpression mixinExpression; 1988 TemplateMixinExpression templateMixinExpression; 1989 **/ 1990 1991 with(mixinDeclaration) 1992 { 1993 putAttrs(attrs); 1994 if (mixinExpression) format(mixinExpression); 1995 else format(templateMixinExpression); 1996 put(";"); 1997 } 1998 } 1999 2000 void format(const MixinExpression mixinExpression) 2001 { 2002 debug(verbose) writeln("MixinExpression"); 2003 2004 put("mixin ("); 2005 format(mixinExpression.assignExpression); 2006 put(")"); 2007 } 2008 2009 void format(const MixinTemplateDeclaration mixinTemplateDeclaration, const Attribute[] attrs = null) 2010 { 2011 debug(verbose) writeln("MixinTemplateDeclaration"); 2012 2013 putAttrs(attrs); 2014 put("mixin "); 2015 format(mixinTemplateDeclaration.templateDeclaration); 2016 } 2017 2018 void format(const MixinTemplateName mixinTemplateName) 2019 { 2020 debug(verbose) writeln("MixinTemplateName"); 2021 2022 /** 2023 Symbol symbol; 2024 IdentifierOrTemplateChain identifierOrTemplateChain; 2025 TypeofExpression typeofExpression; 2026 **/ 2027 2028 with(mixinTemplateName) 2029 { 2030 if (symbol) format(symbol); 2031 else 2032 { 2033 format(typeofExpression); 2034 put("."); 2035 format(identifierOrTemplateChain); 2036 } 2037 } 2038 } 2039 2040 void format(const Module module_) 2041 { 2042 debug(verbose) writeln("Module"); 2043 2044 /** 2045 ModuleDeclaration moduleDeclaration; 2046 Declaration[] declarations; 2047 **/ 2048 2049 format(module_.moduleDeclaration); 2050 foreach(decl; module_.declarations) 2051 format(decl); 2052 } 2053 2054 void format(const ModuleDeclaration moduleDeclaration) 2055 { 2056 debug(verbose) writeln("ModuleDeclaration"); 2057 if (moduleDeclaration is null) return; 2058 2059 /** 2060 IdentifierChain moduleName; 2061 **/ 2062 2063 put("module "); 2064 format(moduleDeclaration.moduleName); 2065 put(";"); 2066 newlineIndent(); 2067 newlineIndent(); 2068 } 2069 2070 void format(const MulExpression mulExpression) 2071 { 2072 debug(verbose) writeln("MulExpression"); 2073 mixin(binary("mulExpression")); 2074 } 2075 2076 void format(const NewAnonClassExpression newAnonClassExpression) 2077 { 2078 debug(verbose) writeln("NewAnonClassExpression"); 2079 2080 /** 2081 Arguments allocatorArguments; 2082 Arguments constructorArguments; 2083 BaseClassList baseClassList; 2084 StructBody structBody; 2085 **/ 2086 2087 with(newAnonClassExpression) 2088 { 2089 if (allocatorArguments) 2090 { 2091 format(allocatorArguments); 2092 space(); 2093 } 2094 put("class"); 2095 if (constructorArguments) 2096 format(constructorArguments); 2097 2098 if (baseClassList) 2099 { 2100 space(); 2101 format(baseClassList); 2102 } 2103 2104 format(structBody); 2105 } 2106 } 2107 2108 void format(const NewExpression newExpression) 2109 { 2110 debug(verbose) writeln("NewExpression"); 2111 2112 /** 2113 Type type; 2114 NewAnonClassExpression newAnonClassExpression; 2115 Arguments arguments; 2116 AssignExpression assignExpression; 2117 **/ 2118 2119 with(newExpression) 2120 { 2121 put("new "); 2122 if (newAnonClassExpression) format(newAnonClassExpression); 2123 else 2124 { 2125 if (type) format(type); 2126 if (arguments) format(arguments); 2127 if (assignExpression) 2128 { 2129 put("["); 2130 format(assignExpression); 2131 put("]"); 2132 } 2133 } 2134 } 2135 } 2136 2137 void format(const NonVoidInitializer nonVoidInitializer) 2138 { 2139 debug(verbose) writeln("NonVoidInitializer"); 2140 2141 /** 2142 AssignExpression assignExpression; 2143 ArrayInitializer arrayInitializer; 2144 StructInitializer structInitializer; 2145 **/ 2146 2147 with(nonVoidInitializer) 2148 { 2149 if (assignExpression) format(assignExpression); 2150 else if (arrayInitializer) format(arrayInitializer); 2151 else if (structInitializer) format(structInitializer); 2152 } 2153 } 2154 2155 void format(const Operands operands) 2156 { 2157 debug(verbose) writeln("Operands"); 2158 assert(false); 2159 } 2160 2161 void format(const OrExpression orExpression) 2162 { 2163 debug(verbose) writeln("OrExpression"); 2164 mixin(binary("orExpression", "|")); 2165 } 2166 2167 void format(const OrOrExpression orOrExpression) 2168 { 2169 debug(verbose) writeln("OrOrExpression"); 2170 mixin(binary("orOrExpression", "||")); 2171 } 2172 2173 void format(const OutStatement stmnt) 2174 { 2175 debug(verbose) writeln("OutStatement"); 2176 2177 /** 2178 Token parameter; 2179 BlockStatement blockStatement; 2180 **/ 2181 2182 put("out"); 2183 if (stmnt.parameter != tok!"") 2184 { 2185 put(" ("); 2186 format(stmnt.parameter); 2187 put(")"); 2188 } 2189 format(stmnt.blockStatement); 2190 } 2191 2192 void format(const Parameter parameter) 2193 { 2194 debug(verbose) writeln("Parameter"); 2195 2196 /** 2197 IdType[] parameterAttributes; 2198 Type type; 2199 Token name; 2200 bool vararg; 2201 AssignExpression default_; 2202 TypeSuffix[] cstyle; 2203 **/ 2204 2205 foreach (count, attribute; parameter.parameterAttributes) 2206 { 2207 if (count) space(); 2208 put(tokenRep(attribute)); 2209 } 2210 2211 if (parameter.parameterAttributes.length > 0) 2212 space(); 2213 2214 if (parameter.type !is null) 2215 format(parameter.type); 2216 2217 if (parameter.name.type != tok!"") 2218 { 2219 space(); 2220 put(parameter.name.text); 2221 } 2222 2223 foreach(suffix; parameter.cstyle) 2224 format(suffix); 2225 2226 if (parameter.default_) 2227 { 2228 put(" = "); 2229 format(parameter.default_); 2230 } 2231 2232 if (parameter.vararg) 2233 put("..."); 2234 } 2235 2236 void format(const Parameters parameters) 2237 { 2238 debug(verbose) writeln("Parameters"); 2239 2240 /** 2241 Parameter[] parameters; 2242 bool hasVarargs; 2243 **/ 2244 2245 put("("); 2246 foreach (count, param; parameters.parameters) 2247 { 2248 if (count) put(", "); 2249 format(param); 2250 } 2251 if (parameters.hasVarargs) 2252 { 2253 if (parameters.parameters.length) 2254 put(", "); 2255 put("..."); 2256 } 2257 put(")"); 2258 } 2259 2260 void format(const Postblit postblit, const Attribute[] attrs = null) 2261 { 2262 debug(verbose) writeln("Postblit"); 2263 2264 /** 2265 FunctionBody functionBody; 2266 **/ 2267 2268 newThing(What.functionDecl); 2269 putAttrs(attrs); 2270 put("this(this)"); 2271 2272 foreach(attr; postblit.memberFunctionAttributes) 2273 { 2274 space(); 2275 format(attr); 2276 } 2277 2278 if (postblit.functionBody) 2279 format(postblit.functionBody); 2280 else 2281 put(";"); 2282 } 2283 2284 void format(const PowExpression powExpression) 2285 { 2286 debug(verbose) writeln("PowExpression"); 2287 mixin(binary("powExpression", "^^", true)); 2288 } 2289 2290 void format(const PragmaDeclaration pragmaDeclaration, const Attribute[] attrs = null) 2291 { 2292 debug(verbose) writeln("PragmaDeclaration"); 2293 2294 /** 2295 PragmaExpression pragmaExpression; 2296 **/ 2297 2298 putAttrs(attrs); 2299 format(pragmaDeclaration.pragmaExpression); 2300 put(";"); 2301 } 2302 2303 void format(const PragmaExpression pragmaExpression) 2304 { 2305 debug(verbose) writeln("PragmaExpression"); 2306 2307 /** 2308 Token identifier; 2309 ArgumentList argumentList; 2310 **/ 2311 2312 put("pragma("); 2313 format(pragmaExpression.identifier); 2314 if (pragmaExpression.argumentList) 2315 { 2316 put(", "); 2317 format(pragmaExpression.argumentList); 2318 } 2319 put(")"); 2320 } 2321 2322 void format(const PrimaryExpression primaryExpression) 2323 { 2324 debug(verbose) writeln("PrimaryExpression"); 2325 2326 /** 2327 Token dot; 2328 Token primary; 2329 IdentifierOrTemplateInstance identifierOrTemplateInstance; 2330 Token basicType; 2331 TypeofExpression typeofExpression; 2332 TypeidExpression typeidExpression; 2333 ArrayLiteral arrayLiteral; 2334 AssocArrayLiteral assocArrayLiteral; 2335 Expression expression; 2336 IsExpression isExpression; 2337 LambdaExpression lambdaExpression; 2338 FunctionLiteralExpression functionLiteralExpression; 2339 TraitsExpression traitsExpression; 2340 MixinExpression mixinExpression; 2341 ImportExpression importExpression; 2342 Vector vector; 2343 **/ 2344 2345 with(primaryExpression) 2346 { 2347 if (dot != tok!"") put("."); 2348 if (basicType != tok!"") format(basicType); 2349 if (primary != tok!"") 2350 { 2351 if (basicType != tok!"") put("."); // i.e. : uint.max 2352 format(primary); 2353 } 2354 2355 if (expression) 2356 { 2357 put("("); 2358 format(expression); 2359 put(")"); 2360 } 2361 else if (identifierOrTemplateInstance) 2362 { 2363 format(identifierOrTemplateInstance); 2364 } 2365 else if (typeofExpression) format(typeofExpression); 2366 else if (typeidExpression) format(typeidExpression); 2367 else if (arrayLiteral) format(arrayLiteral); 2368 else if (assocArrayLiteral) format(assocArrayLiteral); 2369 else if (isExpression) format(isExpression); 2370 else if (functionLiteralExpression) format(functionLiteralExpression); 2371 else if (traitsExpression) format(traitsExpression); 2372 else if (mixinExpression) format(mixinExpression); 2373 else if (importExpression) format(importExpression); 2374 else if (vector) format(vector); 2375 } 2376 } 2377 2378 void format(const Register register) 2379 { 2380 debug(verbose) writeln("Register"); 2381 assert(false); 2382 } 2383 2384 void format(const RelExpression relExpression) 2385 { 2386 debug(verbose) writeln("RelExpression"); 2387 mixin(binary("relExpression")); 2388 } 2389 2390 void format(const ReturnStatement returnStatement) 2391 { 2392 debug(verbose) writeln("ReturnStatement"); 2393 2394 put("return"); 2395 if (returnStatement.expression) 2396 { 2397 space(); 2398 format(returnStatement.expression); 2399 } 2400 put(";"); 2401 } 2402 2403 void format(const ScopeGuardStatement scopeGuardStatement) 2404 { 2405 debug(verbose) writeln("ScopeGuardStatement"); 2406 2407 /** 2408 Token identifier; 2409 StatementNoCaseNoDefault statementNoCaseNoDefault; 2410 **/ 2411 2412 with(scopeGuardStatement) 2413 { 2414 put("scope("); 2415 format(identifier); 2416 put(")"); 2417 indent(); 2418 format(statementNoCaseNoDefault); 2419 outdent(); 2420 } 2421 } 2422 2423 void format(const SharedStaticConstructor sharedStaticConstructor, const Attribute[] attrs = null) 2424 { 2425 debug(verbose) writeln("SharedStaticConstructor"); 2426 2427 with(sharedStaticConstructor) 2428 { 2429 newThing(What.functionDecl); 2430 putComment(comment); 2431 putAttrs(attrs); 2432 put("shared static this()"); 2433 format(functionBody); 2434 } 2435 } 2436 2437 void format(const SharedStaticDestructor sharedStaticDestructor, const Attribute[] attrs = null) 2438 { 2439 debug(verbose) writeln("SharedStaticDestructor"); 2440 2441 with(sharedStaticDestructor) 2442 { 2443 newThing(What.functionDecl); 2444 putComment(comment); 2445 putAttrs(attrs); 2446 put("shared static ~this()"); 2447 format(functionBody); 2448 } 2449 } 2450 2451 void format(const ShiftExpression shiftExpression) 2452 { 2453 debug(verbose) writeln("ShiftExpression"); 2454 mixin(binary("shiftExpression")); 2455 } 2456 2457 void format(const SingleImport singleImport) 2458 { 2459 debug(verbose) writeln("SingleImport"); 2460 2461 /** 2462 Token rename; 2463 IdentifierChain identifierChain; 2464 **/ 2465 2466 if (singleImport.rename != tok!"") 2467 { 2468 format(singleImport.rename); 2469 put(" = "); 2470 } 2471 format(singleImport.identifierChain); 2472 } 2473 2474 void format(const Statement statement) 2475 { 2476 debug(verbose) writeln("Statement"); 2477 2478 /** 2479 StatementNoCaseNoDefault statementNoCaseNoDefault; 2480 CaseStatement caseStatement; 2481 CaseRangeStatement caseRangeStatement; 2482 DefaultStatement defaultStatement; 2483 **/ 2484 2485 with(statement) 2486 { 2487 if (statementNoCaseNoDefault) 2488 { 2489 format(statementNoCaseNoDefault); 2490 return; 2491 } 2492 2493 newlineIndent(); 2494 if (caseStatement) format(caseStatement); 2495 else if (caseRangeStatement) format(caseRangeStatement); 2496 else if (defaultStatement) format(defaultStatement); 2497 } 2498 } 2499 2500 void format(const StatementNoCaseNoDefault statementNoCaseNoDefault) 2501 { 2502 debug(verbose) writeln("StatementNoCaseNoDefault"); 2503 2504 string mix(string s) { return "if (" ~ s ~ ") format(" ~ s ~ ");"; } 2505 2506 with(statementNoCaseNoDefault) 2507 { 2508 if (!blockStatement) newlineIndent(); 2509 2510 enum stmnts = TypeTuple!( 2511 "labeledStatement", 2512 "blockStatement", 2513 "ifStatement", 2514 "whileStatement", 2515 "doStatement", 2516 "forStatement", 2517 "foreachStatement", 2518 "switchStatement", 2519 "finalSwitchStatement", 2520 "continueStatement", 2521 "breakStatement", 2522 "returnStatement", 2523 "gotoStatement", 2524 "withStatement", 2525 "synchronizedStatement", 2526 "tryStatement", 2527 "throwStatement", 2528 "scopeGuardStatement", 2529 "asmStatement", 2530 "conditionalStatement", 2531 "staticAssertStatement", 2532 "versionSpecification", 2533 "debugSpecification", 2534 "expressionStatement" 2535 ); 2536 2537 foreach(s; stmnts) 2538 mixin(mix(s)); 2539 } 2540 } 2541 2542 void format(const StaticAssertDeclaration staticAssertDeclaration, const Attribute[] attrs = null) 2543 { 2544 debug(verbose) writeln("StaticAssertDeclaration"); 2545 2546 newThing(What.other); 2547 putAttrs(attrs); 2548 format(staticAssertDeclaration.staticAssertStatement); 2549 put(";"); 2550 } 2551 2552 void format(const StaticAssertStatement staticAssertStatement) 2553 { 2554 debug(verbose) writeln("StaticAssertStatement"); 2555 2556 put("static "); 2557 format(staticAssertStatement.assertExpression); 2558 } 2559 2560 void format(const StaticConstructor staticConstructor, const Attribute[] attrs = null) 2561 { 2562 debug(verbose) writeln("StaticConstructor"); 2563 2564 putAttrs(attrs); 2565 put("static this()"); 2566 format(staticConstructor.functionBody); 2567 } 2568 2569 void format(const StaticDestructor staticDestructor, const Attribute[] attrs = null) 2570 { 2571 debug(verbose) writeln("StaticDestructor"); 2572 2573 putAttrs(attrs); 2574 put("static ~this()"); 2575 format(staticDestructor.functionBody); 2576 } 2577 2578 void format(const StaticIfCondition staticIfCondition) 2579 { 2580 debug(verbose) writeln("StaticIfCondition"); 2581 2582 put("static if ("); 2583 format(staticIfCondition.assignExpression); 2584 put(")"); 2585 } 2586 2587 void format(const StorageClass storageClass) 2588 { 2589 debug(verbose) writeln("StorageClass"); 2590 2591 /** 2592 AtAttribute atAttribute; 2593 Deprecated deprecated_; 2594 LinkageAttribute linkageAttribute; 2595 Token token; 2596 **/ 2597 2598 with(storageClass) 2599 { 2600 if (atAttribute) format(atAttribute); 2601 else if (deprecated_) format(deprecated_); 2602 else if (linkageAttribute) format(linkageAttribute); 2603 else format(token); 2604 } 2605 } 2606 2607 void format(const StructBody structBody) 2608 { 2609 debug(verbose) writeln("StructBody"); 2610 2611 if (structBody.declarations.length > 0) 2612 { 2613 startBlock(); 2614 foreach(count, decl; structBody.declarations) 2615 format(decl); 2616 endBlock(); 2617 } 2618 else 2619 { 2620 space(); 2621 put("{}"); 2622 } 2623 } 2624 2625 void format(const StructDeclaration decl, const Attribute[] attrs = null) 2626 { 2627 debug(verbose) writeln("StructDeclaration"); 2628 2629 /** 2630 Token name; 2631 TemplateParameters templateParameters; 2632 Constraint constraint; 2633 StructBody structBody; 2634 string comment; 2635 **/ 2636 2637 newThing(What.aggregateDecl); 2638 putComment(decl.comment); 2639 putAttrs(attrs); 2640 put("struct "); 2641 format(decl.name); 2642 2643 if (decl.templateParameters) 2644 format(decl.templateParameters); 2645 2646 if (decl.constraint) 2647 { 2648 space(); 2649 format(decl.constraint); 2650 } 2651 2652 if (decl.structBody) 2653 format(decl.structBody); 2654 else 2655 put(";"); 2656 } 2657 2658 void format(const StructInitializer structInitializer) 2659 { 2660 debug(verbose) writeln("StructInitializer"); 2661 2662 put("{"); 2663 format(structInitializer.structMemberInitializers); 2664 put("}"); 2665 } 2666 2667 void format(const StructMemberInitializer structMemberInitializer) 2668 { 2669 debug(verbose) writeln("StructMemberInitializer"); 2670 2671 /** 2672 Token identifier; 2673 NonVoidInitializer nonVoidInitializer; 2674 **/ 2675 2676 with(structMemberInitializer) 2677 { 2678 if (identifier != tok!"") 2679 { 2680 format(identifier); 2681 put(":"); 2682 } 2683 format(nonVoidInitializer); 2684 } 2685 } 2686 2687 void format(const StructMemberInitializers structMemberInitializers) 2688 { 2689 debug(verbose) writeln("StructMemberInitializers"); 2690 2691 foreach(count, mem; structMemberInitializers.structMemberInitializers) 2692 { 2693 if (count) put(", "); 2694 format(mem); 2695 } 2696 } 2697 2698 void format(const SwitchStatement switchStatement, bool isFinal = false) 2699 { 2700 debug(verbose) writeln("SwitchStatement"); 2701 2702 /** 2703 Expression expression; 2704 Statement statement; 2705 **/ 2706 2707 with(switchStatement) 2708 { 2709 newThing(What.other); 2710 isFinal ? put(" final switch(") : put("switch("); 2711 format(expression); 2712 put(")"); 2713 2714 bool needBlock = statement.statementNoCaseNoDefault && 2715 !(statement.statementNoCaseNoDefault.withStatement || 2716 statement.statementNoCaseNoDefault.blockStatement ); 2717 2718 if (needBlock) 2719 startBlock(); 2720 format(statement); 2721 if (needBlock) 2722 endBlock(); 2723 } 2724 } 2725 2726 void format(const Symbol symbol) 2727 { 2728 debug(verbose) writeln("Symbol"); 2729 2730 if (symbol.dot) 2731 put("."); 2732 format(symbol.identifierOrTemplateChain); 2733 } 2734 2735 void format(const SynchronizedStatement synchronizedStatement) 2736 { 2737 debug(verbose) writeln("SynchronizedStatement"); 2738 2739 /** 2740 Expression expression; 2741 StatementNoCaseNoDefault statementNoCaseNoDefault; 2742 **/ 2743 2744 with(synchronizedStatement) 2745 { 2746 put("synchronized"); 2747 if (expression) 2748 { 2749 put("("); 2750 format(expression); 2751 put(")"); 2752 } 2753 format(statementNoCaseNoDefault); 2754 } 2755 } 2756 2757 void format(const TemplateAliasParameter templateAliasParameter) 2758 { 2759 debug(verbose) writeln("TemplateAliasParameter"); 2760 2761 /** 2762 Type type; 2763 Token identifier; 2764 Type colonType; 2765 AssignExpression colonExpression; 2766 Type assignType; 2767 AssignExpression assignExpression; 2768 **/ 2769 2770 with(templateAliasParameter) 2771 { 2772 put("alias "); 2773 if (type) 2774 { 2775 format(type); 2776 space(); 2777 } 2778 format(identifier); 2779 if (colonType) 2780 { 2781 put(" : "); 2782 format(colonType); 2783 } 2784 else if (colonExpression) 2785 { 2786 put(" : "); 2787 format(colonExpression); 2788 } 2789 if (assignType) 2790 { 2791 put(" = "); 2792 format(assignType); 2793 } 2794 else if (assignExpression) 2795 { 2796 put(" = "); 2797 format(assignExpression); 2798 } 2799 } 2800 } 2801 2802 void format(const TemplateArgument templateArgument) 2803 { 2804 debug(verbose) writeln("TemplateArgument"); 2805 2806 /** 2807 Type type; 2808 AssignExpression assignExpression; 2809 **/ 2810 2811 with(templateArgument) 2812 { 2813 if (type) format(type); 2814 if (assignExpression) format(assignExpression); 2815 } 2816 } 2817 2818 void format(const TemplateArgumentList templateArgumentList, bool parens = true) 2819 { 2820 debug(verbose) writeln("TemplateArgumentList"); 2821 2822 if (parens) put("!("); 2823 foreach(count, arg; templateArgumentList.items) 2824 { 2825 if (count) put(", "); 2826 format(arg); 2827 } 2828 if (parens) put(")"); 2829 } 2830 2831 void format(const TemplateArguments templateArguments) 2832 { 2833 debug(verbose) writeln("TemplateArguments"); 2834 2835 /** 2836 TemplateArgumentList templateArgumentList; 2837 TemplateSingleArgument templateSingleArgument; 2838 **/ 2839 2840 with(templateArguments) 2841 { 2842 if (templateArgumentList) format(templateArgumentList); 2843 else if (templateSingleArgument) format(templateSingleArgument); 2844 else put("!()"); 2845 } 2846 } 2847 2848 void format(const TemplateDeclaration templateDeclaration, const Attribute[] attrs = null) 2849 { 2850 debug(verbose) writeln("TemplateDeclaration"); 2851 2852 /** 2853 Token name; 2854 TemplateParameters templateParameters; 2855 Constraint constraint; 2856 Declaration[] declarations; 2857 EponymousTemplateDeclaration eponymousTemplateDeclaration; 2858 string comment; 2859 **/ 2860 2861 with(templateDeclaration) 2862 { 2863 newThing(What.other); 2864 putComment(comment); 2865 putAttrs(attrs); 2866 2867 put("template "); 2868 format(name); 2869 2870 if (templateParameters) 2871 format(templateParameters); 2872 2873 if (constraint) 2874 { 2875 space(); 2876 format(constraint); 2877 } 2878 2879 startBlock(); 2880 foreach(d; declarations) 2881 format(d); 2882 endBlock(); 2883 } 2884 } 2885 2886 void format(const TemplateInstance templateInstance) 2887 { 2888 debug(verbose) writeln("TemplateInstance"); 2889 2890 /** 2891 Token identifier; 2892 TemplateArguments templateArguments; 2893 **/ 2894 2895 with(templateInstance) 2896 { 2897 format(identifier); 2898 if (templateArguments) format(templateArguments); 2899 } 2900 } 2901 2902 void format(const TemplateMixinExpression templateMixinExpression) 2903 { 2904 debug(verbose) writeln("TemplateMixinExpression"); 2905 2906 /** 2907 Token identifier; 2908 TemplateArguments templateArguments; 2909 MixinTemplateName mixinTemplateName; 2910 **/ 2911 2912 with(templateMixinExpression) 2913 { 2914 put("mixin "); 2915 format(mixinTemplateName); 2916 if (templateArguments) format(templateArguments); 2917 space(); 2918 format(identifier); 2919 } 2920 } 2921 2922 void format(const TemplateParameter templateParameter) 2923 { 2924 debug(verbose) writeln("TemplateParameter"); 2925 2926 with(templateParameter) 2927 { 2928 if (templateTypeParameter) 2929 format(templateTypeParameter); 2930 else if (templateValueParameter) 2931 format(templateValueParameter); 2932 else if (templateAliasParameter) 2933 format(templateAliasParameter); 2934 else if (templateTupleParameter) 2935 format(templateTupleParameter); 2936 else if (templateThisParameter) 2937 format(templateThisParameter); 2938 } 2939 } 2940 2941 void format(const TemplateParameterList templateParameterList) 2942 { 2943 debug(verbose) writeln("TemplateParameterList"); 2944 2945 foreach(i, param; templateParameterList.items) 2946 { 2947 if (i) put(", "); 2948 format(param); 2949 } 2950 } 2951 2952 void format(const TemplateParameters templateParameters) 2953 { 2954 debug(verbose) writeln("TemplateParameters"); 2955 2956 with(templateParameters) 2957 { 2958 put("("); 2959 if (templateParameterList) 2960 format(templateParameterList); 2961 put(")"); 2962 } 2963 } 2964 2965 void format(const TemplateSingleArgument templateSingleArgument) 2966 { 2967 debug(verbose) writeln("TemplateSingleArgument"); 2968 2969 /** 2970 Token token; 2971 **/ 2972 2973 put("!"); 2974 format(templateSingleArgument.token); 2975 } 2976 2977 void format(const TemplateThisParameter templateThisParameter) 2978 { 2979 debug(verbose) writeln("TemplateThisParameter"); 2980 2981 with(templateThisParameter) 2982 { 2983 put("this "); 2984 if (templateTypeParameter) 2985 format(templateTypeParameter); 2986 } 2987 } 2988 2989 void format(const TemplateTupleParameter templateTupleParameter) 2990 { 2991 debug(verbose) writeln("TemplateTupleParameter"); 2992 2993 format(templateTupleParameter.identifier); 2994 put("..."); 2995 } 2996 2997 void format(const TemplateTypeParameter templateTypeParameter) 2998 { 2999 debug(verbose) writeln("TemplateTypeParameter"); 3000 3001 /** 3002 Token identifier; 3003 Type colonType; 3004 Type assignType; 3005 **/ 3006 3007 with(templateTypeParameter) 3008 { 3009 format(identifier); 3010 if (colonType) 3011 { 3012 put(" : "); 3013 format(colonType); 3014 } 3015 if (assignType) 3016 { 3017 put(" = "); 3018 format(assignType); 3019 } 3020 } 3021 } 3022 3023 void format(const TemplateValueParameter templateValueParameter) 3024 { 3025 debug(verbose) writeln("TemplateValueParameter"); 3026 3027 /** 3028 Type type; 3029 Token identifier; 3030 Expression expression; 3031 TemplateValueParameterDefault templateValueParameterDefault; 3032 **/ 3033 3034 with(templateValueParameter) 3035 { 3036 if (type) format(type); 3037 space(); 3038 format(identifier); 3039 3040 if (assignExpression) 3041 { 3042 put(" : "); 3043 format(assignExpression); 3044 } 3045 3046 if (templateValueParameterDefault) 3047 { 3048 put(" = "); 3049 format(templateValueParameterDefault); 3050 } 3051 } 3052 } 3053 3054 void format(const TemplateValueParameterDefault templateValueParameterDefault) 3055 { 3056 debug(verbose) writeln("TemplateValueParameterDefault"); 3057 3058 with(templateValueParameterDefault) 3059 assignExpression ? format(assignExpression) : format(token); 3060 } 3061 3062 void format(const TernaryExpression expr) 3063 { 3064 debug(verbose) writeln("TernaryExpression"); 3065 3066 /** 3067 ExpressionNode orOrExpression; 3068 ExpressionNode expression; 3069 ExpressionNode ternaryExpression; 3070 **/ 3071 3072 format(expr.orOrExpression); 3073 3074 if (expr.expression && expr.ternaryExpression) 3075 { 3076 put(" ? "); 3077 format(expr.expression); 3078 put(" : "); 3079 format(expr.ternaryExpression); 3080 } 3081 } 3082 3083 void format(const ThrowStatement throwStatement) 3084 { 3085 debug(verbose) writeln("ThrowStatement"); 3086 3087 put("throw "); 3088 assert(throwStatement.expression); 3089 format(throwStatement.expression); 3090 put(";"); 3091 } 3092 3093 void format(const Token token) 3094 { 3095 debug(verbose) writeln("Token ", tokenRep(token)); 3096 put(tokenRep(token)); 3097 } 3098 3099 void format(const TraitsExpression traitExpr) 3100 { 3101 debug(verbose) writeln("TraitsExpression"); 3102 3103 /** 3104 Token identifier; 3105 TemplateArgumentList templateArgumentList; 3106 **/ 3107 3108 put("__traits("); 3109 format(traitExpr.identifier); 3110 put(", "); 3111 format(traitExpr.templateArgumentList, false); 3112 put(")"); 3113 } 3114 3115 void format(const TryStatement tryStatement) 3116 { 3117 debug(verbose) writeln("TryStatement"); 3118 3119 /** 3120 DeclarationOrStatement declarationOrStatement; 3121 Catches catches; 3122 Finally finally_; 3123 **/ 3124 3125 with(tryStatement) 3126 { 3127 newThing(What.other); 3128 put("try"); 3129 maybeIndent(declarationOrStatement); 3130 if (catches) format(catches); 3131 if (finally_) format(finally_); 3132 } 3133 } 3134 3135 void format(const Type type) 3136 { 3137 debug(verbose) writeln("Type("); 3138 3139 /** 3140 IdType[] typeConstructors; 3141 TypeSuffix[] typeSuffixes; 3142 Type2 type2; 3143 **/ 3144 3145 foreach (count, constructor; type.typeConstructors) 3146 { 3147 if (count) space(); 3148 put(tokenRep(constructor)); 3149 } 3150 3151 if (type.typeConstructors.length) space(); 3152 format(type.type2); 3153 3154 foreach (suffix; type.typeSuffixes) 3155 format(suffix); 3156 3157 debug(verbose) writeln(")"); 3158 } 3159 3160 void format(const Type2 type2) 3161 { 3162 debug(verbose) writeln("Type2"); 3163 3164 /** 3165 IdType builtinType; 3166 Symbol symbol; 3167 TypeofExpression typeofExpression; 3168 IdentifierOrTemplateChain identifierOrTemplateChain; 3169 IdType typeConstructor; 3170 Type type; 3171 **/ 3172 3173 if (type2.symbol !is null) 3174 { 3175 format(type2.symbol); 3176 } 3177 else if (type2.typeofExpression !is null) 3178 { 3179 format(type2.typeofExpression); 3180 if (type2.identifierOrTemplateChain) 3181 { 3182 put("."); 3183 format(type2.identifierOrTemplateChain); 3184 } 3185 return; 3186 } 3187 else if (type2.typeConstructor != tok!"") 3188 { 3189 put(tokenRep(type2.typeConstructor)); 3190 put("("); 3191 format(type2.type); 3192 put(")"); 3193 } 3194 else 3195 { 3196 put(tokenRep(type2.builtinType)); 3197 if (type2.identifierOrTemplateChain !is null) 3198 { 3199 put("."); 3200 format(type2.identifierOrTemplateChain); 3201 } 3202 } 3203 } 3204 3205 void format(const TypeSpecialization typeSpecialization) 3206 { 3207 debug(verbose) writeln("TypeSpecialization"); 3208 3209 /** 3210 Token token; 3211 Type type; 3212 **/ 3213 3214 with(typeSpecialization) 3215 { 3216 format(token); 3217 if (type) format(type); 3218 } 3219 } 3220 3221 void format(const TypeSuffix typeSuffix) 3222 { 3223 debug(verbose) writeln("TypeSuffix"); 3224 3225 /** 3226 Token delegateOrFunction; 3227 bool star; 3228 bool array; 3229 Type type; 3230 AssignExpression low; 3231 AssignExpression high; 3232 Parameters parameters; 3233 MemberFunctionAttribute[] memberFunctionAttributes; 3234 **/ 3235 3236 if (typeSuffix.star.type != tok!"") 3237 { 3238 put("*"); 3239 return; 3240 } 3241 else if (typeSuffix.array) 3242 { 3243 if (typeSuffix.type is null) 3244 { 3245 if (typeSuffix.low is null) 3246 { 3247 put("[]"); 3248 return; 3249 } 3250 else 3251 { 3252 if (typeSuffix.high is null) 3253 { 3254 put("["); 3255 format(typeSuffix.low); 3256 put("]"); 3257 return; 3258 } 3259 else 3260 { 3261 put("["); 3262 format(typeSuffix.low); 3263 put(".."); 3264 format(typeSuffix.high); 3265 put("]"); 3266 return; 3267 } 3268 } 3269 } 3270 else 3271 { 3272 put("["); 3273 format(typeSuffix.type); 3274 put("]"); 3275 return; 3276 } 3277 } 3278 else 3279 { 3280 space(); 3281 format(typeSuffix.delegateOrFunction); 3282 if (typeSuffix.parameters) format(typeSuffix.parameters); 3283 foreach(attr; typeSuffix.memberFunctionAttributes) 3284 { 3285 space(); 3286 format(attr); 3287 } 3288 return; 3289 } 3290 } 3291 3292 void format(const TypeidExpression idExpr) 3293 { 3294 debug(verbose) writeln("TypeidExpression"); 3295 3296 /** 3297 Type type; 3298 Expression expression; 3299 **/ 3300 3301 put("typeid ("); 3302 idExpr.type ? format(idExpr.type) : format(idExpr.expression); 3303 put(")"); 3304 } 3305 3306 void format(const TypeofExpression typeofExpr) 3307 { 3308 debug(verbose) writeln("TypeofExpression"); 3309 3310 /** 3311 Expression expression; 3312 Token return_; 3313 **/ 3314 3315 put("typeof("); 3316 typeofExpr.expression ? format(typeofExpr.expression) : format(typeofExpr.return_); 3317 put(")"); 3318 } 3319 3320 void format(const UnaryExpression unary) 3321 { 3322 debug(verbose) writeln("UnaryExpression("); 3323 3324 /** 3325 Type type; 3326 PrimaryExpression primaryExpression; 3327 Token prefix; 3328 Token suffix; 3329 UnaryExpression unaryExpression; 3330 NewExpression newExpression; 3331 DeleteExpression deleteExpression; 3332 CastExpression castExpression; 3333 FunctionCallExpression functionCallExpression; 3334 ArgumentList argumentList; 3335 IdentifierOrTemplateInstance identifierOrTemplateInstance; 3336 AssertExpression assertExpression; 3337 SliceExpression sliceExpression; 3338 IndexExpression indexExpression; 3339 **/ 3340 3341 with(unary) 3342 { 3343 if (prefix != tok!"") format(prefix); 3344 3345 if (type) 3346 { 3347 // handle things like (void*).sizeof 3348 if (identifierOrTemplateInstance) 3349 { 3350 put("("); 3351 format(type); 3352 put(")"); 3353 } 3354 else 3355 { 3356 format(type); 3357 put("("); 3358 if (argumentList) 3359 format(argumentList); 3360 put(")"); 3361 } 3362 } 3363 3364 if (primaryExpression) format(primaryExpression); 3365 if (newExpression) format(newExpression); 3366 if (deleteExpression) format(deleteExpression); 3367 if (castExpression) format(castExpression); 3368 if (functionCallExpression) format(functionCallExpression); 3369 if (assertExpression) format(assertExpression); 3370 if (indexExpression) format(indexExpression); 3371 3372 if (unaryExpression) format(unaryExpression); 3373 if (suffix != tok!"") format(suffix); 3374 3375 if (identifierOrTemplateInstance) 3376 { 3377 put("."); 3378 format(identifierOrTemplateInstance); 3379 } 3380 } 3381 3382 debug(verbose) writeln(")"); 3383 } 3384 3385 void format(const UnionDeclaration decl, const Attribute[] attrs = null) 3386 { 3387 debug(verbose) writeln("UnionDeclaration"); 3388 3389 /** 3390 Token name; 3391 TemplateParameters templateParameters; 3392 Constraint constraint; 3393 StructBody structBody; 3394 string comment; 3395 **/ 3396 3397 newThing(What.aggregateDecl); 3398 putComment(decl.comment); 3399 putAttrs(attrs); 3400 put("union "); 3401 format(decl.name); 3402 if (decl.templateParameters) 3403 format(decl.templateParameters); 3404 if (decl.constraint) 3405 { 3406 space(); 3407 format(decl.constraint); 3408 } 3409 format(decl.structBody); 3410 } 3411 3412 void format(const Unittest unittest_, const Attribute[] attrs = null) 3413 { 3414 debug(verbose) writeln("Unittest"); 3415 3416 /** 3417 BlockStatement blockStatement; 3418 string comment; 3419 **/ 3420 3421 newThing(What.functionDecl); 3422 putComment(unittest_.comment); 3423 putAttrs(attrs); 3424 put("unittest"); 3425 format(unittest_.blockStatement); 3426 } 3427 3428 void format(const VariableDeclaration decl, const Attribute[] attrs = null) 3429 { 3430 debug(verbose) writeln("VariableDeclaration"); 3431 3432 /** 3433 Type type; 3434 Declarator[] declarators; 3435 StorageClass storageClass; 3436 AutoDeclaration autoDeclaration; 3437 string comment; 3438 **/ 3439 3440 newThing(What.variableDecl); 3441 putComment(decl.comment); 3442 putAttrs(attrs); 3443 3444 if (decl.autoDeclaration) 3445 format(decl.autoDeclaration); 3446 else 3447 { 3448 foreach (c; decl.storageClasses) 3449 { 3450 format(c); 3451 space(); 3452 } 3453 if (decl.type) format(decl.type); 3454 if (decl.declarators.length) space(); 3455 foreach(count, d; decl.declarators) 3456 { 3457 if (count) put(", "); 3458 format(d); 3459 } 3460 } 3461 put(";"); 3462 } 3463 3464 void format(const Vector vector) 3465 { 3466 debug(verbose) writeln("Vector"); 3467 3468 put("__vector("); 3469 format(vector.type); 3470 put(")"); 3471 } 3472 3473 void format(const VersionCondition versionCondition) 3474 { 3475 debug(verbose) writeln("VersionCondition"); 3476 3477 put("version ("); 3478 format(versionCondition.token); 3479 put(")"); 3480 } 3481 3482 void format(const VersionSpecification ver, const Attribute[] attrs = null) 3483 { 3484 debug(verbose) writeln("VersionSpecification"); 3485 3486 newThing(What.other); 3487 putAttrs(attrs); 3488 put("version = "); 3489 format(ver.token); 3490 put(";"); 3491 } 3492 3493 void format(const WhileStatement stmt) 3494 { 3495 debug(verbose) writeln("WhileStatement"); 3496 3497 /** 3498 Expression expression; 3499 DeclarationOrStatement declarationOrStatement; 3500 **/ 3501 3502 newThing(What.other); 3503 put("while ("); 3504 format(stmt.expression); 3505 put(")"); 3506 maybeIndent(stmt.declarationOrStatement); 3507 } 3508 3509 void format(const WithStatement stmt) 3510 { 3511 debug(verbose) writeln("WithStatement"); 3512 3513 /** 3514 Expression expression; 3515 StatementNoCaseNoDefault statementNoCaseNoDefault; 3516 **/ 3517 3518 space(); 3519 put("with ("); 3520 format(stmt.expression); 3521 put(")"); 3522 format(stmt.statementNoCaseNoDefault); 3523 } 3524 3525 void format(const XorExpression xorExpression) 3526 { 3527 debug(verbose) writeln("XorExpression"); 3528 mixin(binary("xorExpression", "^")); 3529 } 3530 3531 Sink sink; 3532 3533 protected: 3534 3535 import std.uni : isWhite; 3536 3537 void indent() 3538 { 3539 indentLevel++; 3540 } 3541 3542 void outdent() 3543 { 3544 if (indentLevel == 0) 3545 return; 3546 indentLevel--; 3547 } 3548 3549 void putIndent() 3550 { 3551 if (!indentLevel) return; 3552 auto i = getIndent(); 3553 put(i); 3554 } 3555 3556 string getIndent() 3557 { 3558 if (useTabs) 3559 { 3560 char[] c = new char[indentLevel]; 3561 c[] = '\t'; 3562 return cast(string) c; 3563 } 3564 else 3565 { 3566 char[] c = new char[indentLevel * indentWidth]; 3567 c[] = ' '; 3568 return cast(string) c; 3569 } 3570 } 3571 3572 enum What 3573 { 3574 functionDecl, 3575 aggregateDecl, 3576 attributeDecl, 3577 conditionalDecl, 3578 variableDecl, 3579 importDecl, 3580 expr, 3581 loop, 3582 else_, 3583 catch_, 3584 other 3585 } 3586 3587 void newThing(What thing) 3588 { 3589 lastThing = currentThing; 3590 currentThing = thing; 3591 3592 with(What) { 3593 3594 if (lastThing == importDecl && thing != importDecl) 3595 { 3596 lineGap(1); 3597 return; 3598 } 3599 3600 if (lastThing == loop) 3601 { 3602 lineGap(1); 3603 return; 3604 } 3605 3606 switch(thing) 3607 { 3608 case other: 3609 newline(); 3610 break; 3611 case aggregateDecl: 3612 case attributeDecl: 3613 case functionDecl: 3614 lineGap(1); 3615 break; 3616 case conditionalDecl: 3617 lineGap(1); 3618 break; 3619 case variableDecl: 3620 lineGap(1); 3621 break; 3622 case importDecl: 3623 newlineIndent(); 3624 break; 3625 case expr: break; 3626 case catch_: goto case; 3627 case else_: 3628 final switch(style) with(IndentStyle) 3629 { 3630 case allman: newline(); break; 3631 case otbs: space(); break; 3632 } 3633 break; 3634 default: newlineIndent(); break; 3635 } 3636 } 3637 } 3638 3639 void lineGap(int gap) 3640 { 3641 foreach (i; 0 .. gap + 1) 3642 { 3643 if (i == gap) 3644 newlineIndent(); 3645 else 3646 newline(); 3647 } 3648 } 3649 3650 void newlineIndent() 3651 { 3652 if (ignoreNewlines) 3653 { 3654 space(); // don't do this when splitting lines 3655 } 3656 else 3657 { 3658 sink.put("\n"); 3659 lineLength = 0; 3660 putIndent(); 3661 } 3662 } 3663 3664 void newline() 3665 { 3666 sink.put("\n"); 3667 lineLength = 0; 3668 } 3669 3670 void space() 3671 { 3672 put(" "); 3673 } 3674 3675 static string binary(string symbol, string operator = null, bool nospace = false) 3676 { 3677 return "with(" ~ symbol ~ "){" 3678 ~ "format(left); if (right is null) return;" 3679 ~ (nospace ? "" : "put(` `);") 3680 ~ (operator ? "put(`" ~ operator ~ "`);" : "put(tokenRep(operator));") 3681 ~ (nospace ? "" : "put(` `);") 3682 ~ "format(right);}"; 3683 } 3684 3685 void startBlock() 3686 { 3687 final switch(style) with(IndentStyle) 3688 { 3689 case allman: newline(); break; 3690 case otbs: space(); break; 3691 } 3692 putIndent(); 3693 put("{"); 3694 indent(); 3695 } 3696 3697 void endBlock() 3698 { 3699 outdent(); 3700 newline(); 3701 putIndent(); 3702 put("}"); 3703 } 3704 3705 string tokenRep(Token t) 3706 { 3707 return t.text.length ? t.text : tokenRep(t.type); 3708 } 3709 3710 string tokenRep(IdType t) 3711 { 3712 return t ? str(t) : ""; 3713 } 3714 3715 void putComment(string c) 3716 { 3717 import std.string : splitLines; 3718 if (!c.length) return; 3719 put(c.splitLines().join("\n" ~ getIndent())); 3720 newlineIndent(); 3721 } 3722 3723 void putAttrs(const Attribute[] attrs) 3724 { 3725 if (attrs !is null) 3726 { 3727 foreach(count, attr; attrs) 3728 { 3729 format(attr); 3730 space(); 3731 } 3732 } 3733 } 3734 3735 void put(string s) 3736 { 3737 sink.put(s); 3738 lineLength += s.length; // TODO: tabs / spaces? 3739 } 3740 3741 void formatCaseDecls(const DeclarationsAndStatements declsAndStmnts) 3742 { 3743 bool seenBlock = false; 3744 auto items = declsAndStmnts.declarationsAndStatements; 3745 foreach(item; items) 3746 { 3747 bool _indent = false; 3748 if (item.declaration) _indent = true; 3749 if (item.statement && item.statement.statementNoCaseNoDefault) 3750 { 3751 if (item.statement.statementNoCaseNoDefault.blockStatement) 3752 seenBlock = true; 3753 else if (!item.statement.statementNoCaseNoDefault.labeledStatement) 3754 _indent = true; 3755 } 3756 if (seenBlock) _indent = false; 3757 if (_indent) indent(); 3758 format(item); 3759 if (_indent) outdent(); 3760 } 3761 } 3762 3763 bool needIndent(const Statement s) 3764 { 3765 return s.statementNoCaseNoDefault && 3766 !s.statementNoCaseNoDefault.blockStatement; 3767 } 3768 3769 bool needIndent(const Declaration d) 3770 { 3771 return !d.declarations.length; 3772 } 3773 3774 bool needIndent(const DeclarationOrStatement dors) 3775 { 3776 return (dors.declaration && needIndent(dors.declaration)) || 3777 (dors.statement && needIndent(dors.statement)); 3778 } 3779 3780 void maybeIndent(T)(const T t) 3781 { 3782 auto _indent = needIndent(t); 3783 if (_indent) indent(); 3784 format(t); 3785 if (_indent) outdent(); 3786 } 3787 3788 bool isEmptyDeclaration(const Declaration decl) 3789 { 3790 with(decl) 3791 { 3792 string mix(string[] s) { 3793 string r; 3794 foreach(c, d; s) 3795 r ~= (c > 0 ? "else " : "") ~ "if (" ~ d ~ ") return false;"; 3796 return r; 3797 } 3798 mixin(mix(possibleDeclarations)); 3799 return attributes.length == 0 && 3800 declarations.length == 0; 3801 } 3802 } 3803 3804 bool ignoreNewlines = false; 3805 bool useTabs; 3806 uint caseDepth; 3807 uint indentWidth; 3808 uint indentLevel; 3809 IndentStyle style; 3810 3811 3812 What lastThing, currentThing; 3813 uint lineLength; 3814 uint maxLineLength = 80; 3815 3816 enum possibleDeclarations = [ 3817 "attributeDeclaration", 3818 "importDeclaration", 3819 "functionDeclaration", 3820 "variableDeclaration", 3821 "aliasThisDeclaration", 3822 "structDeclaration", 3823 "classDeclaration", 3824 "interfaceDeclaration", 3825 "unionDeclaration", 3826 "enumDeclaration", 3827 "aliasDeclaration", 3828 "mixinDeclaration", 3829 "mixinTemplateDeclaration", 3830 "unittest_", 3831 "staticAssertDeclaration", 3832 "templateDeclaration", 3833 "constructor", 3834 "destructor", 3835 "staticConstructor", 3836 "staticDestructor", 3837 "sharedStaticDestructor", 3838 "sharedStaticConstructor", 3839 "conditionalDeclaration", 3840 "pragmaDeclaration", 3841 "versionSpecification", 3842 "invariant_", 3843 "postblit" 3844 ]; 3845 }