1 /** 2 * D Documentation Generator 3 * Copyright: © 2014 Economic Modeling Specialists, Intl., © 2014 Ferdinand Majerech 4 * Authors: Brian Schott, Ferdinand Majerech 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost License 1.0) 6 */ 7 module formatter; 8 9 import dparse.ast; 10 import dparse.lexer; 11 import dparse.formatter; 12 import std.stdio; 13 14 15 /** Modified D formatter for Harbored. 16 * 17 * Currently the only modification is that multi-parameter parameter lists are split into 18 * multiple lines. 19 */ 20 class HarboredFormatter(Sink) : Formatter!Sink 21 { 22 /// Nesting level for nested parameter lists (see format(const Parameters)). 23 private uint level; 24 25 /// Function to process types with for cross-referencing. 26 private string delegate(string) @safe nothrow crossReference; 27 28 /** 29 * Params: 30 * 31 * sink = the output range that the formatted source code is placed in 32 * processCode = Function to process types with for cross-referencing. 33 * useTabs = if true, tabs are used for indent levels instead of spaces 34 * style = the brace style 35 * indentWidth = the number of spaces used for indentation if useTabs is false 36 */ 37 this(Sink sink, string delegate(string) @safe nothrow crossReference, 38 bool useTabs = false, IndentStyle style = IndentStyle.allman, uint indentWidth = 4) 39 { 40 this.crossReference = crossReference; 41 super(sink, useTabs, style, indentWidth); 42 } 43 44 alias format = Formatter!Sink.format; 45 46 /** A modified version of (libdparse) std.d.formatter.Formatter.format(const Parameters) 47 * to format each parameter on a separate line. 48 */ 49 override void format(const Parameters parameters) 50 { 51 debug (verbose) writeln("Parameters (HarboredFormatter)"); 52 53 import std.range : iota; 54 import std.algorithm.iteration : each; 55 alias indent = {iota(level).each!(a => (put(" ")));}; 56 57 // No need to break the list into multiple lines for a single argument 58 // TODO ability to set this in "doxyfile" 59 const maxParametersForSingleLineParameterList = 1; 60 if (parameters.parameters.length <= maxParametersForSingleLineParameterList) 61 { 62 super.format(parameters); 63 return; 64 } 65 level++; 66 scope(exit) level--; 67 put("("); 68 foreach (count, param; parameters.parameters) 69 { 70 if (count) 71 put(", "); 72 put("\n"); 73 indent(); 74 format(param); 75 } 76 if (parameters.hasVarargs) 77 { 78 if (parameters.parameters.length) 79 put(", "); 80 put("\n"); 81 indent(); 82 put("..."); 83 } 84 if (level > 1) 85 { 86 put("\n"); 87 indent(); 88 } 89 put(")"); 90 } 91 92 // Overridden for builtin type referencing. 93 override void format(const Type2 type2) 94 { 95 debug(verbose) writeln("Type2 (HarboredFormatter)"); 96 97 /** 98 IdType builtinType; 99 Symbol symbol; 100 TypeofExpression typeofExpression; 101 IdentifierOrTemplateChain identifierOrTemplateChain; 102 IdType typeConstructor; 103 Type type; 104 **/ 105 106 if (type2.typeIdentifierPart !is null) 107 { 108 format(type2.typeIdentifierPart); 109 } 110 else if (type2.typeofExpression !is null) 111 { 112 format(type2.typeofExpression); 113 if (type2.typeIdentifierPart) 114 { 115 put("."); 116 format(type2.typeIdentifierPart); 117 } 118 return; 119 } 120 else if (type2.typeConstructor != tok!"") 121 { 122 put(tokenRep(type2.typeConstructor)); 123 put("("); 124 format(type2.type); 125 put(")"); 126 } 127 else 128 { 129 // Link to language reference for builtin types. 130 put(`<a href="http://dlang.org/type.html#basic-data-types">`); 131 put(tokenRep(type2.builtinType)); 132 put("</a>"); 133 } 134 } 135 136 // Overridden for cross-referencing. 137 override void format(const Token token) 138 { 139 debug(verbose) writeln("Token (HarboredFormatter) ", tokenRep(token)); 140 put(crossReference(tokenRep(token))); 141 } 142 } 143