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