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