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