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