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