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 } else if(linkageAttribute.identifier.text == "Objective") 2035 put("-C"); 2036 put(")"); 2037 } 2038 2039 void format(const MemberFunctionAttribute memberFunctionAttribute) 2040 { 2041 debug(verbose) writeln("MemberFunctionAttribute"); 2042 2043 /** 2044 IdType tokenType; 2045 AtAttribute atAttribute; 2046 **/ 2047 2048 with(memberFunctionAttribute) 2049 { 2050 if (tokenType) put(tokenRep(tokenType)); 2051 else format(atAttribute); 2052 } 2053 } 2054 2055 void format(const MixinDeclaration mixinDeclaration, const Attribute[] attrs = null) 2056 { 2057 debug(verbose) writeln("MixinDeclaration"); 2058 2059 /** 2060 MixinExpression mixinExpression; 2061 TemplateMixinExpression templateMixinExpression; 2062 **/ 2063 2064 with(mixinDeclaration) 2065 { 2066 putAttrs(attrs); 2067 if (mixinExpression) format(mixinExpression); 2068 else format(templateMixinExpression); 2069 put(";"); 2070 } 2071 } 2072 2073 void format(const MixinExpression mixinExpression) 2074 { 2075 debug(verbose) writeln("MixinExpression"); 2076 2077 put("mixin ("); 2078 format(mixinExpression.assignExpression); 2079 put(")"); 2080 } 2081 2082 void format(const MixinTemplateDeclaration mixinTemplateDeclaration, const Attribute[] attrs = null) 2083 { 2084 debug(verbose) writeln("MixinTemplateDeclaration"); 2085 2086 putAttrs(attrs); 2087 put("mixin "); 2088 format(mixinTemplateDeclaration.templateDeclaration); 2089 } 2090 2091 void format(const MixinTemplateName mixinTemplateName) 2092 { 2093 debug(verbose) writeln("MixinTemplateName"); 2094 2095 /** 2096 Symbol symbol; 2097 IdentifierOrTemplateChain identifierOrTemplateChain; 2098 TypeofExpression typeofExpression; 2099 **/ 2100 2101 with(mixinTemplateName) 2102 { 2103 if (symbol) format(symbol); 2104 else 2105 { 2106 format(typeofExpression); 2107 put("."); 2108 format(identifierOrTemplateChain); 2109 } 2110 } 2111 } 2112 2113 void format(const Module module_) 2114 { 2115 debug(verbose) writeln("Module"); 2116 2117 /** 2118 ModuleDeclaration moduleDeclaration; 2119 Declaration[] declarations; 2120 **/ 2121 2122 format(module_.moduleDeclaration); 2123 foreach(decl; module_.declarations) 2124 format(decl); 2125 } 2126 2127 void format(const ModuleDeclaration moduleDeclaration) 2128 { 2129 debug(verbose) writeln("ModuleDeclaration"); 2130 if (moduleDeclaration is null) return; 2131 2132 /** 2133 IdentifierChain moduleName; 2134 **/ 2135 2136 put("module "); 2137 format(moduleDeclaration.moduleName); 2138 put(";"); 2139 newlineIndent(); 2140 newlineIndent(); 2141 } 2142 2143 void format(const MulExpression mulExpression) 2144 { 2145 debug(verbose) writeln("MulExpression"); 2146 mixin(binary("mulExpression")); 2147 } 2148 2149 void format(const NewAnonClassExpression newAnonClassExpression) 2150 { 2151 debug(verbose) writeln("NewAnonClassExpression"); 2152 2153 /** 2154 Arguments allocatorArguments; 2155 Arguments constructorArguments; 2156 BaseClassList baseClassList; 2157 StructBody structBody; 2158 **/ 2159 2160 with(newAnonClassExpression) 2161 { 2162 if (allocatorArguments) 2163 { 2164 format(allocatorArguments); 2165 space(); 2166 } 2167 put("class"); 2168 if (constructorArguments) 2169 format(constructorArguments); 2170 2171 if (baseClassList) 2172 { 2173 space(); 2174 format(baseClassList); 2175 } 2176 2177 format(structBody); 2178 } 2179 } 2180 2181 void format(const NewExpression newExpression) 2182 { 2183 debug(verbose) writeln("NewExpression"); 2184 2185 /** 2186 Type type; 2187 NewAnonClassExpression newAnonClassExpression; 2188 Arguments arguments; 2189 AssignExpression assignExpression; 2190 **/ 2191 2192 with(newExpression) 2193 { 2194 put("new "); 2195 if (newAnonClassExpression) format(newAnonClassExpression); 2196 else 2197 { 2198 if (type) format(type); 2199 if (arguments) format(arguments); 2200 if (assignExpression) 2201 { 2202 put("["); 2203 format(assignExpression); 2204 put("]"); 2205 } 2206 } 2207 } 2208 } 2209 2210 void format(const NonVoidInitializer nonVoidInitializer) 2211 { 2212 debug(verbose) writeln("NonVoidInitializer"); 2213 2214 /** 2215 AssignExpression assignExpression; 2216 ArrayInitializer arrayInitializer; 2217 StructInitializer structInitializer; 2218 **/ 2219 2220 with(nonVoidInitializer) 2221 { 2222 if (assignExpression) format(assignExpression); 2223 else if (arrayInitializer) format(arrayInitializer); 2224 else if (structInitializer) format(structInitializer); 2225 } 2226 } 2227 2228 void format(const Operands operands) 2229 { 2230 debug(verbose) writeln("Operands"); 2231 assert(false); 2232 } 2233 2234 void format(const OrExpression orExpression) 2235 { 2236 debug(verbose) writeln("OrExpression"); 2237 mixin(binary("orExpression", "|")); 2238 } 2239 2240 void format(const OrOrExpression orOrExpression) 2241 { 2242 debug(verbose) writeln("OrOrExpression"); 2243 mixin(binary("orOrExpression", "||")); 2244 } 2245 2246 void format(const OutStatement stmnt) 2247 { 2248 debug(verbose) writeln("OutStatement"); 2249 2250 /** 2251 Token parameter; 2252 BlockStatement blockStatement; 2253 **/ 2254 2255 put("out"); 2256 if(stmnt.expression) { 2257 put(" ("); 2258 format(stmnt.parameter); 2259 put("; "); 2260 format(stmnt.expression); 2261 put(")"); 2262 return; 2263 } 2264 if (stmnt.parameter != tok!"") 2265 { 2266 put(" ("); 2267 format(stmnt.parameter); 2268 put(")"); 2269 } 2270 if(stmnt.blockStatement) 2271 format(stmnt.blockStatement); 2272 } 2273 2274 void format(const Parameter parameter) 2275 { 2276 debug(verbose) writeln("Parameter"); 2277 2278 /** 2279 IdType[] parameterAttributes; 2280 Type type; 2281 Token name; 2282 bool vararg; 2283 AssignExpression default_; 2284 TypeSuffix[] cstyle; 2285 **/ 2286 2287 bool hadAtAttribute; 2288 2289 foreach (count, attribute; parameter.atAttributes) 2290 { 2291 hadAtAttribute = true; 2292 if (count) space(); 2293 format(attribute); 2294 } 2295 2296 foreach (count, attribute; parameter.parameterAttributes) 2297 { 2298 if (count || hadAtAttribute) space(); 2299 put(tokenRep(attribute)); 2300 } 2301 2302 if (parameter.parameterAttributes.length > 0) 2303 space(); 2304 2305 if (parameter.type !is null) 2306 format(parameter.type); 2307 2308 if (parameter.name.type != tok!"") 2309 { 2310 space(); 2311 put(parameter.name.text); 2312 } 2313 2314 foreach(suffix; parameter.cstyle) 2315 format(suffix); 2316 2317 if (parameter.default_) 2318 { 2319 put(" = "); 2320 format(parameter.default_); 2321 } 2322 2323 if (parameter.vararg) 2324 put("..."); 2325 } 2326 2327 void format(const Parameters parameters) 2328 { 2329 debug(verbose) writeln("Parameters"); 2330 2331 /** 2332 Parameter[] parameters; 2333 bool hasVarargs; 2334 **/ 2335 2336 put("("); 2337 foreach (count, param; parameters.parameters) 2338 { 2339 if (count) put(", "); 2340 format(param); 2341 } 2342 if (parameters.hasVarargs) 2343 { 2344 if (parameters.parameters.length) 2345 put(", "); 2346 put("..."); 2347 } 2348 put(")"); 2349 } 2350 2351 void format(const Postblit postblit, const Attribute[] attrs = null) 2352 { 2353 debug(verbose) writeln("Postblit"); 2354 2355 /** 2356 FunctionBody functionBody; 2357 **/ 2358 2359 newThing(What.functionDecl); 2360 putAttrs(attrs); 2361 put("this(this)"); 2362 2363 foreach(attr; postblit.memberFunctionAttributes) 2364 { 2365 space(); 2366 format(attr); 2367 } 2368 2369 if (postblit.functionBody) 2370 format(postblit.functionBody); 2371 else 2372 put(";"); 2373 } 2374 2375 void format(const PowExpression powExpression) 2376 { 2377 debug(verbose) writeln("PowExpression"); 2378 mixin(binary("powExpression", "^^", true)); 2379 } 2380 2381 void format(const PragmaDeclaration pragmaDeclaration, const Attribute[] attrs = null) 2382 { 2383 debug(verbose) writeln("PragmaDeclaration"); 2384 2385 /** 2386 PragmaExpression pragmaExpression; 2387 **/ 2388 2389 putAttrs(attrs); 2390 format(pragmaDeclaration.pragmaExpression); 2391 put(";"); 2392 } 2393 2394 void format(const PragmaExpression pragmaExpression) 2395 { 2396 debug(verbose) writeln("PragmaExpression"); 2397 2398 /** 2399 Token identifier; 2400 ArgumentList argumentList; 2401 **/ 2402 2403 put("pragma("); 2404 format(pragmaExpression.identifier); 2405 if (pragmaExpression.argumentList) 2406 { 2407 put(", "); 2408 format(pragmaExpression.argumentList); 2409 } 2410 put(")"); 2411 } 2412 2413 void format(const PrimaryExpression primaryExpression) 2414 { 2415 debug(verbose) writeln("PrimaryExpression"); 2416 2417 /** 2418 Token dot; 2419 Token primary; 2420 IdentifierOrTemplateInstance identifierOrTemplateInstance; 2421 Token basicType; 2422 TypeofExpression typeofExpression; 2423 TypeidExpression typeidExpression; 2424 ArrayLiteral arrayLiteral; 2425 AssocArrayLiteral assocArrayLiteral; 2426 Expression expression; 2427 IsExpression isExpression; 2428 LambdaExpression lambdaExpression; 2429 FunctionLiteralExpression functionLiteralExpression; 2430 TraitsExpression traitsExpression; 2431 MixinExpression mixinExpression; 2432 ImportExpression importExpression; 2433 Vector vector; 2434 **/ 2435 2436 with(primaryExpression) 2437 { 2438 if (dot != tok!"") put("."); 2439 if (basicType != tok!"") format(basicType); 2440 if (primary != tok!"") 2441 { 2442 if (basicType != tok!"") put("."); // i.e. : uint.max 2443 format(primary); 2444 } 2445 2446 if (expression) 2447 { 2448 put("("); 2449 format(expression); 2450 put(")"); 2451 } 2452 else if (identifierOrTemplateInstance) 2453 { 2454 format(identifierOrTemplateInstance); 2455 } 2456 else if (typeofExpression) format(typeofExpression); 2457 else if (typeidExpression) format(typeidExpression); 2458 else if (arrayLiteral) format(arrayLiteral); 2459 else if (assocArrayLiteral) format(assocArrayLiteral); 2460 else if (isExpression) format(isExpression); 2461 else if (lambdaExpression) format(lambdaExpression); 2462 else if (functionLiteralExpression) format(functionLiteralExpression); 2463 else if (traitsExpression) format(traitsExpression); 2464 else if (mixinExpression) format(mixinExpression); 2465 else if (importExpression) format(importExpression); 2466 else if (vector) format(vector); 2467 } 2468 } 2469 2470 void format(const Register register) 2471 { 2472 debug(verbose) writeln("Register"); 2473 assert(false); 2474 } 2475 2476 void format(const RelExpression relExpression) 2477 { 2478 debug(verbose) writeln("RelExpression"); 2479 mixin(binary("relExpression")); 2480 } 2481 2482 void format(const ReturnStatement returnStatement) 2483 { 2484 debug(verbose) writeln("ReturnStatement"); 2485 2486 put("return"); 2487 if (returnStatement.expression) 2488 { 2489 space(); 2490 format(returnStatement.expression); 2491 } 2492 put(";"); 2493 } 2494 2495 void format(const ScopeGuardStatement scopeGuardStatement) 2496 { 2497 debug(verbose) writeln("ScopeGuardStatement"); 2498 2499 /** 2500 Token identifier; 2501 StatementNoCaseNoDefault statementNoCaseNoDefault; 2502 **/ 2503 2504 with(scopeGuardStatement) 2505 { 2506 put("scope("); 2507 format(identifier); 2508 put(")"); 2509 indent(); 2510 format(statementNoCaseNoDefault); 2511 outdent(); 2512 } 2513 } 2514 2515 void format(const SharedStaticConstructor sharedStaticConstructor, const Attribute[] attrs = null) 2516 { 2517 debug(verbose) writeln("SharedStaticConstructor"); 2518 2519 with(sharedStaticConstructor) 2520 { 2521 newThing(What.functionDecl); 2522 putComment(comment); 2523 putAttrs(attrs); 2524 put("shared static this()"); 2525 format(functionBody); 2526 } 2527 } 2528 2529 void format(const SharedStaticDestructor sharedStaticDestructor, const Attribute[] attrs = null) 2530 { 2531 debug(verbose) writeln("SharedStaticDestructor"); 2532 2533 with(sharedStaticDestructor) 2534 { 2535 newThing(What.functionDecl); 2536 putComment(comment); 2537 putAttrs(attrs); 2538 put("shared static ~this()"); 2539 format(functionBody); 2540 } 2541 } 2542 2543 void format(const ShiftExpression shiftExpression) 2544 { 2545 debug(verbose) writeln("ShiftExpression"); 2546 mixin(binary("shiftExpression")); 2547 } 2548 2549 void format(const SingleImport singleImport) 2550 { 2551 debug(verbose) writeln("SingleImport"); 2552 2553 /** 2554 Token rename; 2555 IdentifierChain identifierChain; 2556 **/ 2557 2558 if (singleImport.rename != tok!"") 2559 { 2560 format(singleImport.rename); 2561 put(" = "); 2562 } 2563 format(singleImport.identifierChain); 2564 } 2565 2566 void format(const Statement statement) 2567 { 2568 debug(verbose) writeln("Statement"); 2569 2570 /** 2571 StatementNoCaseNoDefault statementNoCaseNoDefault; 2572 CaseStatement caseStatement; 2573 CaseRangeStatement caseRangeStatement; 2574 DefaultStatement defaultStatement; 2575 **/ 2576 2577 with(statement) 2578 { 2579 if (statementNoCaseNoDefault) 2580 { 2581 format(statementNoCaseNoDefault); 2582 return; 2583 } 2584 2585 newlineIndent(); 2586 if (caseStatement) format(caseStatement); 2587 else if (caseRangeStatement) format(caseRangeStatement); 2588 else if (defaultStatement) format(defaultStatement); 2589 } 2590 } 2591 2592 void format(const StatementNoCaseNoDefault statementNoCaseNoDefault) 2593 { 2594 debug(verbose) writeln("StatementNoCaseNoDefault"); 2595 2596 string mix(string s) { return "if (" ~ s ~ ") format(" ~ s ~ ");"; } 2597 2598 with(statementNoCaseNoDefault) 2599 { 2600 if (!blockStatement) newlineIndent(); 2601 2602 enum stmnts = TypeTuple!( 2603 "labeledStatement", 2604 "blockStatement", 2605 "ifStatement", 2606 "whileStatement", 2607 "doStatement", 2608 "forStatement", 2609 "foreachStatement", 2610 "switchStatement", 2611 "finalSwitchStatement", 2612 "continueStatement", 2613 "breakStatement", 2614 "returnStatement", 2615 "gotoStatement", 2616 "withStatement", 2617 "synchronizedStatement", 2618 "tryStatement", 2619 "throwStatement", 2620 "scopeGuardStatement", 2621 "asmStatement", 2622 "conditionalStatement", 2623 "staticAssertStatement", 2624 "versionSpecification", 2625 "debugSpecification", 2626 "expressionStatement" 2627 ); 2628 2629 foreach(s; stmnts) 2630 mixin(mix(s)); 2631 } 2632 } 2633 2634 void format(const StaticAssertDeclaration staticAssertDeclaration, const Attribute[] attrs = null) 2635 { 2636 debug(verbose) writeln("StaticAssertDeclaration"); 2637 2638 newThing(What.other); 2639 putAttrs(attrs); 2640 format(staticAssertDeclaration.staticAssertStatement); 2641 put(";"); 2642 } 2643 2644 void format(const StaticAssertStatement staticAssertStatement) 2645 { 2646 debug(verbose) writeln("StaticAssertStatement"); 2647 2648 put("static "); 2649 format(staticAssertStatement.assertExpression); 2650 } 2651 2652 void format(const StaticConstructor staticConstructor, const Attribute[] attrs = null) 2653 { 2654 debug(verbose) writeln("StaticConstructor"); 2655 2656 putAttrs(attrs); 2657 put("static this()"); 2658 format(staticConstructor.functionBody); 2659 } 2660 2661 void format(const StaticDestructor staticDestructor, const Attribute[] attrs = null) 2662 { 2663 debug(verbose) writeln("StaticDestructor"); 2664 2665 putAttrs(attrs); 2666 put("static ~this()"); 2667 format(staticDestructor.functionBody); 2668 } 2669 2670 void format(const StaticIfCondition staticIfCondition) 2671 { 2672 debug(verbose) writeln("StaticIfCondition"); 2673 2674 put("static if ("); 2675 format(staticIfCondition.assignExpression); 2676 put(")"); 2677 } 2678 2679 void format(const StorageClass storageClass) 2680 { 2681 debug(verbose) writeln("StorageClass"); 2682 2683 /** 2684 AtAttribute atAttribute; 2685 Deprecated deprecated_; 2686 LinkageAttribute linkageAttribute; 2687 Token token; 2688 **/ 2689 2690 with(storageClass) 2691 { 2692 if (atAttribute) format(atAttribute); 2693 else if (deprecated_) format(deprecated_); 2694 else if (linkageAttribute) format(linkageAttribute); 2695 else format(token); 2696 } 2697 } 2698 2699 void format(const StructBody structBody) 2700 { 2701 debug(verbose) writeln("StructBody"); 2702 2703 if (structBody.declarations.length > 0) 2704 { 2705 startBlock(); 2706 foreach(count, decl; structBody.declarations) 2707 format(decl); 2708 endBlock(); 2709 } 2710 else 2711 { 2712 space(); 2713 put("{}"); 2714 } 2715 } 2716 2717 void format(const StructDeclaration decl, const Attribute[] attrs = null) 2718 { 2719 debug(verbose) writeln("StructDeclaration"); 2720 2721 /** 2722 Token name; 2723 TemplateParameters templateParameters; 2724 Constraint constraint; 2725 StructBody structBody; 2726 string comment; 2727 **/ 2728 2729 newThing(What.aggregateDecl); 2730 putComment(decl.comment); 2731 putAttrs(attrs); 2732 put("struct "); 2733 format(decl.name); 2734 2735 if (decl.templateParameters) 2736 format(decl.templateParameters); 2737 2738 if (decl.constraint) 2739 { 2740 space(); 2741 format(decl.constraint); 2742 } 2743 2744 if (decl.structBody) 2745 format(decl.structBody); 2746 else 2747 put(";"); 2748 } 2749 2750 void format(const StructInitializer structInitializer) 2751 { 2752 debug(verbose) writeln("StructInitializer"); 2753 2754 put("{"); 2755 format(structInitializer.structMemberInitializers); 2756 put("}"); 2757 } 2758 2759 void format(const StructMemberInitializer structMemberInitializer) 2760 { 2761 debug(verbose) writeln("StructMemberInitializer"); 2762 2763 /** 2764 Token identifier; 2765 NonVoidInitializer nonVoidInitializer; 2766 **/ 2767 2768 with(structMemberInitializer) 2769 { 2770 if (identifier != tok!"") 2771 { 2772 format(identifier); 2773 put(":"); 2774 } 2775 format(nonVoidInitializer); 2776 } 2777 } 2778 2779 void format(const StructMemberInitializers structMemberInitializers) 2780 { 2781 debug(verbose) writeln("StructMemberInitializers"); 2782 2783 foreach(count, mem; structMemberInitializers.structMemberInitializers) 2784 { 2785 if (count) put(", "); 2786 format(mem); 2787 } 2788 } 2789 2790 void format(const SwitchStatement switchStatement, bool isFinal = false) 2791 { 2792 debug(verbose) writeln("SwitchStatement"); 2793 2794 /** 2795 Expression expression; 2796 Statement statement; 2797 **/ 2798 2799 with(switchStatement) 2800 { 2801 newThing(What.other); 2802 isFinal ? put(" final switch(") : put("switch("); 2803 format(expression); 2804 put(")"); 2805 2806 bool needBlock = statement.statementNoCaseNoDefault && 2807 !(statement.statementNoCaseNoDefault.withStatement || 2808 statement.statementNoCaseNoDefault.blockStatement ); 2809 2810 if (needBlock) 2811 startBlock(); 2812 format(statement); 2813 if (needBlock) 2814 endBlock(); 2815 } 2816 } 2817 2818 void format(const Symbol symbol) 2819 { 2820 debug(verbose) writeln("Symbol"); 2821 2822 if (symbol.dot) 2823 put("."); 2824 format(symbol.identifierOrTemplateChain); 2825 } 2826 2827 void format(const SynchronizedStatement synchronizedStatement) 2828 { 2829 debug(verbose) writeln("SynchronizedStatement"); 2830 2831 /** 2832 Expression expression; 2833 StatementNoCaseNoDefault statementNoCaseNoDefault; 2834 **/ 2835 2836 with(synchronizedStatement) 2837 { 2838 put("synchronized"); 2839 if (expression) 2840 { 2841 put("("); 2842 format(expression); 2843 put(")"); 2844 } 2845 format(statementNoCaseNoDefault); 2846 } 2847 } 2848 2849 void format(const TemplateAliasParameter templateAliasParameter) 2850 { 2851 debug(verbose) writeln("TemplateAliasParameter"); 2852 2853 /** 2854 Type type; 2855 Token identifier; 2856 Type colonType; 2857 AssignExpression colonExpression; 2858 Type assignType; 2859 AssignExpression assignExpression; 2860 **/ 2861 2862 with(templateAliasParameter) 2863 { 2864 put("alias "); 2865 if (type) 2866 { 2867 format(type); 2868 space(); 2869 } 2870 format(identifier); 2871 if (colonType) 2872 { 2873 put(" : "); 2874 format(colonType); 2875 } 2876 else if (colonExpression) 2877 { 2878 put(" : "); 2879 format(colonExpression); 2880 } 2881 if (assignType) 2882 { 2883 put(" = "); 2884 format(assignType); 2885 } 2886 else if (assignExpression) 2887 { 2888 put(" = "); 2889 format(assignExpression); 2890 } 2891 } 2892 } 2893 2894 void format(const TemplateArgument templateArgument) 2895 { 2896 debug(verbose) writeln("TemplateArgument"); 2897 2898 /** 2899 Type type; 2900 AssignExpression assignExpression; 2901 **/ 2902 2903 with(templateArgument) 2904 { 2905 if (type) format(type); 2906 if (assignExpression) format(assignExpression); 2907 } 2908 } 2909 2910 void format(const TemplateArgumentList templateArgumentList, bool parens = true) 2911 { 2912 debug(verbose) writeln("TemplateArgumentList"); 2913 2914 if (parens) put("!("); 2915 foreach(count, arg; templateArgumentList.items) 2916 { 2917 if (count) put(", "); 2918 format(arg); 2919 } 2920 if (parens) put(")"); 2921 } 2922 2923 void format(const TemplateArguments templateArguments) 2924 { 2925 debug(verbose) writeln("TemplateArguments"); 2926 2927 /** 2928 TemplateArgumentList templateArgumentList; 2929 TemplateSingleArgument templateSingleArgument; 2930 **/ 2931 2932 with(templateArguments) 2933 { 2934 if (templateArgumentList) format(templateArgumentList); 2935 else if (templateSingleArgument) format(templateSingleArgument); 2936 else put("!()"); 2937 } 2938 } 2939 2940 void format(const TemplateDeclaration templateDeclaration, const Attribute[] attrs = null) 2941 { 2942 debug(verbose) writeln("TemplateDeclaration"); 2943 2944 /** 2945 Token name; 2946 TemplateParameters templateParameters; 2947 Constraint constraint; 2948 Declaration[] declarations; 2949 EponymousTemplateDeclaration eponymousTemplateDeclaration; 2950 string comment; 2951 **/ 2952 2953 with(templateDeclaration) 2954 { 2955 newThing(What.other); 2956 putComment(comment); 2957 putAttrs(attrs); 2958 2959 put("template "); 2960 format(name); 2961 2962 if (templateParameters) 2963 format(templateParameters); 2964 2965 if (constraint) 2966 { 2967 space(); 2968 format(constraint); 2969 } 2970 2971 startBlock(); 2972 foreach(d; declarations) 2973 format(d); 2974 endBlock(); 2975 } 2976 } 2977 2978 void format(const TemplateInstance templateInstance) 2979 { 2980 debug(verbose) writeln("TemplateInstance"); 2981 2982 /** 2983 Token identifier; 2984 TemplateArguments templateArguments; 2985 **/ 2986 2987 with(templateInstance) 2988 { 2989 format(identifier); 2990 if (templateArguments) format(templateArguments); 2991 } 2992 } 2993 2994 void format(const TemplateMixinExpression templateMixinExpression) 2995 { 2996 debug(verbose) writeln("TemplateMixinExpression"); 2997 2998 /** 2999 Token identifier; 3000 TemplateArguments templateArguments; 3001 MixinTemplateName mixinTemplateName; 3002 **/ 3003 3004 with(templateMixinExpression) 3005 { 3006 put("mixin "); 3007 format(mixinTemplateName); 3008 if (templateArguments) format(templateArguments); 3009 space(); 3010 format(identifier); 3011 } 3012 } 3013 3014 void format(const TemplateParameter templateParameter) 3015 { 3016 debug(verbose) writeln("TemplateParameter"); 3017 3018 with(templateParameter) 3019 { 3020 if (templateTypeParameter) 3021 format(templateTypeParameter); 3022 else if (templateValueParameter) 3023 format(templateValueParameter); 3024 else if (templateAliasParameter) 3025 format(templateAliasParameter); 3026 else if (templateTupleParameter) 3027 format(templateTupleParameter); 3028 else if (templateThisParameter) 3029 format(templateThisParameter); 3030 } 3031 } 3032 3033 void format(const TemplateParameterList templateParameterList) 3034 { 3035 debug(verbose) writeln("TemplateParameterList"); 3036 3037 foreach(i, param; templateParameterList.items) 3038 { 3039 if (i) put(", "); 3040 format(param); 3041 } 3042 } 3043 3044 void format(const TemplateParameters templateParameters) 3045 { 3046 debug(verbose) writeln("TemplateParameters"); 3047 3048 with(templateParameters) 3049 { 3050 put("("); 3051 if (templateParameterList) 3052 format(templateParameterList); 3053 put(")"); 3054 } 3055 } 3056 3057 void format(const TemplateSingleArgument templateSingleArgument) 3058 { 3059 debug(verbose) writeln("TemplateSingleArgument"); 3060 3061 /** 3062 Token token; 3063 **/ 3064 3065 put("!"); 3066 format(templateSingleArgument.token); 3067 } 3068 3069 void format(const TemplateThisParameter templateThisParameter) 3070 { 3071 debug(verbose) writeln("TemplateThisParameter"); 3072 3073 with(templateThisParameter) 3074 { 3075 put("this "); 3076 if (templateTypeParameter) 3077 format(templateTypeParameter); 3078 } 3079 } 3080 3081 void format(const TemplateTupleParameter templateTupleParameter) 3082 { 3083 debug(verbose) writeln("TemplateTupleParameter"); 3084 3085 format(templateTupleParameter.identifier); 3086 put("..."); 3087 } 3088 3089 void format(const TemplateTypeParameter templateTypeParameter) 3090 { 3091 debug(verbose) writeln("TemplateTypeParameter"); 3092 3093 /** 3094 Token identifier; 3095 Type colonType; 3096 Type assignType; 3097 **/ 3098 3099 with(templateTypeParameter) 3100 { 3101 format(identifier); 3102 if (colonType) 3103 { 3104 put(" : "); 3105 format(colonType); 3106 } 3107 if (assignType) 3108 { 3109 put(" = "); 3110 format(assignType); 3111 } 3112 } 3113 } 3114 3115 void format(const TemplateValueParameter templateValueParameter) 3116 { 3117 debug(verbose) writeln("TemplateValueParameter"); 3118 3119 /** 3120 Type type; 3121 Token identifier; 3122 Expression expression; 3123 TemplateValueParameterDefault templateValueParameterDefault; 3124 **/ 3125 3126 with(templateValueParameter) 3127 { 3128 if (type) format(type); 3129 space(); 3130 format(identifier); 3131 3132 if (assignExpression) 3133 { 3134 put(" : "); 3135 format(assignExpression); 3136 } 3137 3138 if (templateValueParameterDefault) 3139 { 3140 put(" = "); 3141 format(templateValueParameterDefault); 3142 } 3143 } 3144 } 3145 3146 void format(const TemplateValueParameterDefault templateValueParameterDefault) 3147 { 3148 debug(verbose) writeln("TemplateValueParameterDefault"); 3149 3150 with(templateValueParameterDefault) 3151 assignExpression ? format(assignExpression) : format(token); 3152 } 3153 3154 void format(const TernaryExpression expr) 3155 { 3156 debug(verbose) writeln("TernaryExpression"); 3157 3158 /** 3159 ExpressionNode orOrExpression; 3160 ExpressionNode expression; 3161 ExpressionNode ternaryExpression; 3162 **/ 3163 3164 format(expr.orOrExpression); 3165 3166 if (expr.expression && expr.ternaryExpression) 3167 { 3168 put(" ? "); 3169 format(expr.expression); 3170 put(" : "); 3171 format(expr.ternaryExpression); 3172 } 3173 } 3174 3175 void format(const ThrowStatement throwStatement) 3176 { 3177 debug(verbose) writeln("ThrowStatement"); 3178 3179 put("throw "); 3180 assert(throwStatement.expression); 3181 format(throwStatement.expression); 3182 put(";"); 3183 } 3184 3185 void format(const Token token) 3186 { 3187 debug(verbose) writeln("Token ", tokenRep(token)); 3188 put(tokenRep(token)); 3189 } 3190 3191 void format(const TraitsExpression traitExpr) 3192 { 3193 debug(verbose) writeln("TraitsExpression"); 3194 3195 /** 3196 Token identifier; 3197 TemplateArgumentList templateArgumentList; 3198 **/ 3199 3200 put("__traits("); 3201 format(traitExpr.identifier); 3202 put(", "); 3203 format(traitExpr.templateArgumentList, false); 3204 put(")"); 3205 } 3206 3207 void format(const TryStatement tryStatement) 3208 { 3209 debug(verbose) writeln("TryStatement"); 3210 3211 /** 3212 DeclarationOrStatement declarationOrStatement; 3213 Catches catches; 3214 Finally finally_; 3215 **/ 3216 3217 with(tryStatement) 3218 { 3219 newThing(What.other); 3220 put("try"); 3221 maybeIndent(declarationOrStatement); 3222 if (catches) format(catches); 3223 if (finally_) format(finally_); 3224 } 3225 } 3226 3227 void format(const Type type) 3228 { 3229 debug(verbose) writeln("Type("); 3230 3231 /** 3232 IdType[] typeConstructors; 3233 TypeSuffix[] typeSuffixes; 3234 Type2 type2; 3235 **/ 3236 3237 foreach (count, constructor; type.typeConstructors) 3238 { 3239 if (count) space(); 3240 put(tokenRep(constructor)); 3241 } 3242 3243 if (type.typeConstructors.length) space(); 3244 format(type.type2); 3245 3246 foreach (suffix; type.typeSuffixes) 3247 format(suffix); 3248 3249 debug(verbose) writeln(")"); 3250 } 3251 3252 void format(const Type2 type2) 3253 { 3254 debug(verbose) writeln("Type2"); 3255 3256 /** 3257 IdType builtinType; 3258 Symbol symbol; 3259 TypeofExpression typeofExpression; 3260 IdentifierOrTemplateChain identifierOrTemplateChain; 3261 IdType typeConstructor; 3262 Type type; 3263 **/ 3264 3265 if (type2.symbol !is null) 3266 { 3267 format(type2.symbol); 3268 } 3269 else if (type2.typeofExpression !is null) 3270 { 3271 format(type2.typeofExpression); 3272 if (type2.identifierOrTemplateChain) 3273 { 3274 put("."); 3275 format(type2.identifierOrTemplateChain); 3276 } 3277 return; 3278 } 3279 else if (type2.typeConstructor != tok!"") 3280 { 3281 put(tokenRep(type2.typeConstructor)); 3282 put("("); 3283 format(type2.type); 3284 put(")"); 3285 } 3286 else 3287 { 3288 put(tokenRep(type2.builtinType)); 3289 } 3290 } 3291 3292 void format(const TypeSpecialization typeSpecialization) 3293 { 3294 debug(verbose) writeln("TypeSpecialization"); 3295 3296 /** 3297 Token token; 3298 Type type; 3299 **/ 3300 3301 with(typeSpecialization) 3302 { 3303 format(token); 3304 if (type) format(type); 3305 } 3306 } 3307 3308 void format(const TypeSuffix typeSuffix) 3309 { 3310 debug(verbose) writeln("TypeSuffix"); 3311 3312 /** 3313 Token delegateOrFunction; 3314 bool star; 3315 bool array; 3316 Type type; 3317 AssignExpression low; 3318 AssignExpression high; 3319 Parameters parameters; 3320 MemberFunctionAttribute[] memberFunctionAttributes; 3321 **/ 3322 3323 if (typeSuffix.star.type != tok!"") 3324 { 3325 put("*"); 3326 return; 3327 } 3328 else if (typeSuffix.array) 3329 { 3330 if (typeSuffix.type is null) 3331 { 3332 if (typeSuffix.low is null) 3333 { 3334 put("[]"); 3335 return; 3336 } 3337 else 3338 { 3339 if (typeSuffix.high is null) 3340 { 3341 put("["); 3342 format(typeSuffix.low); 3343 put("]"); 3344 return; 3345 } 3346 else 3347 { 3348 put("["); 3349 format(typeSuffix.low); 3350 put(".."); 3351 format(typeSuffix.high); 3352 put("]"); 3353 return; 3354 } 3355 } 3356 } 3357 else 3358 { 3359 put("["); 3360 format(typeSuffix.type); 3361 put("]"); 3362 return; 3363 } 3364 } 3365 else 3366 { 3367 space(); 3368 format(typeSuffix.delegateOrFunction); 3369 if (typeSuffix.parameters) format(typeSuffix.parameters); 3370 foreach(attr; typeSuffix.memberFunctionAttributes) 3371 { 3372 space(); 3373 format(attr); 3374 } 3375 return; 3376 } 3377 } 3378 3379 void format(const TypeidExpression idExpr) 3380 { 3381 debug(verbose) writeln("TypeidExpression"); 3382 3383 /** 3384 Type type; 3385 Expression expression; 3386 **/ 3387 3388 put("typeid ("); 3389 idExpr.type ? format(idExpr.type) : format(idExpr.expression); 3390 put(")"); 3391 } 3392 3393 void format(const TypeofExpression typeofExpr) 3394 { 3395 debug(verbose) writeln("TypeofExpression"); 3396 3397 /** 3398 Expression expression; 3399 Token return_; 3400 **/ 3401 3402 put("typeof("); 3403 typeofExpr.expression ? format(typeofExpr.expression) : format(typeofExpr.return_); 3404 put(")"); 3405 } 3406 3407 void format(const UnaryExpression unary) 3408 { 3409 debug(verbose) writeln("UnaryExpression("); 3410 3411 /** 3412 Type type; 3413 PrimaryExpression primaryExpression; 3414 Token prefix; 3415 Token suffix; 3416 UnaryExpression unaryExpression; 3417 NewExpression newExpression; 3418 DeleteExpression deleteExpression; 3419 CastExpression castExpression; 3420 FunctionCallExpression functionCallExpression; 3421 ArgumentList argumentList; 3422 IdentifierOrTemplateInstance identifierOrTemplateInstance; 3423 AssertExpression assertExpression; 3424 SliceExpression sliceExpression; 3425 IndexExpression indexExpression; 3426 **/ 3427 3428 with(unary) 3429 { 3430 if (prefix != tok!"") format(prefix); 3431 3432 if (type) 3433 { 3434 // handle things like (void*).sizeof 3435 if (identifierOrTemplateInstance) 3436 { 3437 put("("); 3438 format(type); 3439 put(")"); 3440 } 3441 else 3442 { 3443 format(type); 3444 put("("); 3445 if (argumentList) 3446 format(argumentList); 3447 put(")"); 3448 } 3449 } 3450 3451 if (primaryExpression) format(primaryExpression); 3452 if (newExpression) format(newExpression); 3453 if (deleteExpression) format(deleteExpression); 3454 if (castExpression) format(castExpression); 3455 if (functionCallExpression) format(functionCallExpression); 3456 if (assertExpression) format(assertExpression); 3457 if (indexExpression) format(indexExpression); 3458 3459 if (unaryExpression) format(unaryExpression); 3460 if (suffix != tok!"") format(suffix); 3461 3462 if (identifierOrTemplateInstance) 3463 { 3464 put("."); 3465 format(identifierOrTemplateInstance); 3466 } 3467 } 3468 3469 debug(verbose) writeln(")"); 3470 } 3471 3472 void format(const UnionDeclaration decl, const Attribute[] attrs = null) 3473 { 3474 debug(verbose) writeln("UnionDeclaration"); 3475 3476 /** 3477 Token name; 3478 TemplateParameters templateParameters; 3479 Constraint constraint; 3480 StructBody structBody; 3481 string comment; 3482 **/ 3483 3484 newThing(What.aggregateDecl); 3485 putComment(decl.comment); 3486 putAttrs(attrs); 3487 put("union "); 3488 format(decl.name); 3489 if (decl.templateParameters) 3490 format(decl.templateParameters); 3491 if (decl.constraint) 3492 { 3493 space(); 3494 format(decl.constraint); 3495 } 3496 format(decl.structBody); 3497 } 3498 3499 void format(const Unittest unittest_, const Attribute[] attrs = null) 3500 { 3501 debug(verbose) writeln("Unittest"); 3502 3503 /** 3504 BlockStatement blockStatement; 3505 string comment; 3506 **/ 3507 3508 newThing(What.functionDecl); 3509 putComment(unittest_.comment); 3510 putAttrs(attrs); 3511 put("unittest"); 3512 format(unittest_.blockStatement); 3513 } 3514 3515 void format(const VariableDeclaration decl, const Attribute[] attrs = null) 3516 { 3517 debug(verbose) writeln("VariableDeclaration"); 3518 3519 /** 3520 Type type; 3521 Declarator[] declarators; 3522 StorageClass storageClass; 3523 AutoDeclaration autoDeclaration; 3524 string comment; 3525 **/ 3526 3527 newThing(What.variableDecl); 3528 putComment(decl.comment); 3529 putAttrs(attrs); 3530 3531 if (decl.autoDeclaration) 3532 format(decl.autoDeclaration); 3533 else 3534 { 3535 foreach (c; decl.storageClasses) 3536 { 3537 format(c); 3538 space(); 3539 } 3540 if (decl.type) format(decl.type); 3541 if (decl.declarators.length) space(); 3542 foreach(count, d; decl.declarators) 3543 { 3544 if (count) put(", "); 3545 format(d); 3546 } 3547 } 3548 put(";"); 3549 } 3550 3551 void format(const Vector vector) 3552 { 3553 debug(verbose) writeln("Vector"); 3554 3555 put("__vector("); 3556 format(vector.type); 3557 put(")"); 3558 } 3559 3560 void format(const VersionCondition versionCondition) 3561 { 3562 debug(verbose) writeln("VersionCondition"); 3563 3564 put("version ("); 3565 format(versionCondition.token); 3566 put(")"); 3567 } 3568 3569 void format(const VersionSpecification ver, const Attribute[] attrs = null) 3570 { 3571 debug(verbose) writeln("VersionSpecification"); 3572 3573 newThing(What.other); 3574 putAttrs(attrs); 3575 put("version = "); 3576 format(ver.token); 3577 put(";"); 3578 } 3579 3580 void format(const WhileStatement stmt) 3581 { 3582 debug(verbose) writeln("WhileStatement"); 3583 3584 /** 3585 Expression expression; 3586 DeclarationOrStatement declarationOrStatement; 3587 **/ 3588 3589 newThing(What.other); 3590 put("while ("); 3591 format(stmt.expression); 3592 put(")"); 3593 maybeIndent(stmt.declarationOrStatement); 3594 } 3595 3596 void format(const WithStatement stmt) 3597 { 3598 debug(verbose) writeln("WithStatement"); 3599 3600 /** 3601 Expression expression; 3602 StatementNoCaseNoDefault statementNoCaseNoDefault; 3603 **/ 3604 3605 space(); 3606 put("with ("); 3607 format(stmt.expression); 3608 put(")"); 3609 format(stmt.statementNoCaseNoDefault); 3610 } 3611 3612 void format(const XorExpression xorExpression) 3613 { 3614 debug(verbose) writeln("XorExpression"); 3615 mixin(binary("xorExpression", "^")); 3616 } 3617 3618 Sink sink; 3619 3620 protected: 3621 3622 import std.uni : isWhite; 3623 3624 void indent() 3625 { 3626 indentLevel++; 3627 } 3628 3629 void outdent() 3630 { 3631 if (indentLevel == 0) 3632 return; 3633 indentLevel--; 3634 } 3635 3636 void putIndent() 3637 { 3638 if (!indentLevel) return; 3639 auto i = getIndent(); 3640 put(i); 3641 } 3642 3643 string getIndent() 3644 { 3645 if (useTabs) 3646 { 3647 char[] c = new char[indentLevel]; 3648 c[] = '\t'; 3649 return cast(string) c; 3650 } 3651 else 3652 { 3653 char[] c = new char[indentLevel * indentWidth]; 3654 c[] = ' '; 3655 return cast(string) c; 3656 } 3657 } 3658 3659 enum What 3660 { 3661 functionDecl, 3662 aggregateDecl, 3663 attributeDecl, 3664 conditionalDecl, 3665 variableDecl, 3666 importDecl, 3667 expr, 3668 loop, 3669 else_, 3670 catch_, 3671 other 3672 } 3673 3674 void newThing(What thing) 3675 { 3676 lastThing = currentThing; 3677 currentThing = thing; 3678 3679 with(What) { 3680 3681 if (lastThing == importDecl && thing != importDecl) 3682 { 3683 lineGap(1); 3684 return; 3685 } 3686 3687 if (lastThing == loop) 3688 { 3689 lineGap(1); 3690 return; 3691 } 3692 3693 switch(thing) 3694 { 3695 case other: 3696 newline(); 3697 break; 3698 case aggregateDecl: 3699 case attributeDecl: 3700 case functionDecl: 3701 lineGap(1); 3702 break; 3703 case conditionalDecl: 3704 lineGap(1); 3705 break; 3706 case variableDecl: 3707 lineGap(1); 3708 break; 3709 case importDecl: 3710 newlineIndent(); 3711 break; 3712 case expr: break; 3713 case catch_: goto case; 3714 case else_: 3715 final switch(style) with(IndentStyle) 3716 { 3717 case allman: newline(); break; 3718 case otbs: space(); break; 3719 } 3720 break; 3721 default: newlineIndent(); break; 3722 } 3723 } 3724 } 3725 3726 void lineGap(int gap) 3727 { 3728 foreach (i; 0 .. gap + 1) 3729 { 3730 if (i == gap) 3731 newlineIndent(); 3732 else 3733 newline(); 3734 } 3735 } 3736 3737 void newlineIndent() 3738 { 3739 if (ignoreNewlines) 3740 { 3741 space(); // don't do this when splitting lines 3742 } 3743 else 3744 { 3745 sink.put("\n"); 3746 lineLength = 0; 3747 putIndent(); 3748 } 3749 } 3750 3751 void newline() 3752 { 3753 sink.put("\n"); 3754 lineLength = 0; 3755 } 3756 3757 void space() 3758 { 3759 put(" "); 3760 } 3761 3762 static string binary(string symbol, string operator = null, bool nospace = false) 3763 { 3764 return "with(" ~ symbol ~ "){" 3765 ~ "format(left); if (right is null) return;" 3766 ~ (nospace ? "" : "put(` `);") 3767 ~ (operator ? "put(`" ~ operator ~ "`);" : "put(tokenRep(operator));") 3768 ~ (nospace ? "" : "put(` `);") 3769 ~ "format(right);}"; 3770 } 3771 3772 void startBlock() 3773 { 3774 final switch(style) with(IndentStyle) 3775 { 3776 case allman: newline(); break; 3777 case otbs: space(); break; 3778 } 3779 putIndent(); 3780 put("{"); 3781 indent(); 3782 } 3783 3784 void endBlock() 3785 { 3786 outdent(); 3787 newline(); 3788 putIndent(); 3789 put("}"); 3790 } 3791 3792 string tokenRep(Token t) 3793 { 3794 return t.text.length ? t.text : tokenRep(t.type); 3795 } 3796 3797 string tokenRep(IdType t) 3798 { 3799 return t ? str(t) : ""; 3800 } 3801 3802 void putComment(string c) 3803 { 3804 import std.string : splitLines; 3805 if (!c.length) return; 3806 put(c.splitLines().join("\n" ~ getIndent())); 3807 newlineIndent(); 3808 } 3809 3810 void putAttrs(const Attribute[] attrs) 3811 { 3812 if (attrs !is null) 3813 { 3814 foreach(count, attr; attrs) 3815 { 3816 format(attr); 3817 space(); 3818 } 3819 } 3820 } 3821 3822 void put(string s) 3823 { 3824 sink.put(s); 3825 lineLength += s.length; // TODO: tabs / spaces? 3826 } 3827 3828 void formatCaseDecls(const DeclarationsAndStatements declsAndStmnts) 3829 { 3830 bool seenBlock = false; 3831 auto items = declsAndStmnts.declarationsAndStatements; 3832 foreach(item; items) 3833 { 3834 bool _indent = false; 3835 if (item.declaration) _indent = true; 3836 if (item.statement && item.statement.statementNoCaseNoDefault) 3837 { 3838 if (item.statement.statementNoCaseNoDefault.blockStatement) 3839 seenBlock = true; 3840 else if (!item.statement.statementNoCaseNoDefault.labeledStatement) 3841 _indent = true; 3842 } 3843 if (seenBlock) _indent = false; 3844 if (_indent) indent(); 3845 format(item); 3846 if (_indent) outdent(); 3847 } 3848 } 3849 3850 bool needIndent(const Statement s) 3851 { 3852 return s.statementNoCaseNoDefault && 3853 !s.statementNoCaseNoDefault.blockStatement; 3854 } 3855 3856 bool needIndent(const Declaration d) 3857 { 3858 return !d.declarations.length; 3859 } 3860 3861 bool needIndent(const DeclarationOrStatement dors) 3862 { 3863 return (dors.declaration && needIndent(dors.declaration)) || 3864 (dors.statement && needIndent(dors.statement)); 3865 } 3866 3867 void maybeIndent(T)(const T t) 3868 { 3869 auto _indent = needIndent(t); 3870 if (_indent) indent(); 3871 format(t); 3872 if (_indent) outdent(); 3873 } 3874 3875 bool isEmptyDeclaration(const Declaration decl) 3876 { 3877 with(decl) 3878 { 3879 string mix(string[] s) { 3880 string r; 3881 foreach(c, d; s) 3882 r ~= (c > 0 ? "else " : "") ~ "if (" ~ d ~ ") return false;"; 3883 return r; 3884 } 3885 mixin(mix(possibleDeclarations)); 3886 return attributes.length == 0 && 3887 declarations.length == 0; 3888 } 3889 } 3890 3891 bool ignoreNewlines = false; 3892 bool useTabs; 3893 uint caseDepth; 3894 uint indentWidth; 3895 uint indentLevel; 3896 IndentStyle style; 3897 3898 3899 What lastThing, currentThing; 3900 uint lineLength; 3901 uint maxLineLength = 80; 3902 3903 enum possibleDeclarations = [ 3904 "attributeDeclaration", 3905 "importDeclaration", 3906 "functionDeclaration", 3907 "variableDeclaration", 3908 "aliasThisDeclaration", 3909 "structDeclaration", 3910 "classDeclaration", 3911 "interfaceDeclaration", 3912 "unionDeclaration", 3913 "enumDeclaration", 3914 "aliasDeclaration", 3915 "mixinDeclaration", 3916 "mixinTemplateDeclaration", 3917 "unittest_", 3918 "staticAssertDeclaration", 3919 "templateDeclaration", 3920 "constructor", 3921 "destructor", 3922 "staticConstructor", 3923 "staticDestructor", 3924 "sharedStaticDestructor", 3925 "sharedStaticConstructor", 3926 "conditionalDeclaration", 3927 "pragmaDeclaration", 3928 "versionSpecification", 3929 "invariant_", 3930 "postblit" 3931 ]; 3932 }