diff --git a/src/dfmt/ast_info.d b/src/dfmt/ast_info.d index d72e082..7b1dade 100644 --- a/src/dfmt/ast_info.d +++ b/src/dfmt/ast_info.d @@ -8,10 +8,19 @@ module dfmt.ast_info; import dparse.lexer; import dparse.ast; +enum BraceIndentInfoFlags +{ + tempIndent = 1 << 0, +} + struct BraceIndentInfo { size_t startLocation; size_t endLocation; + + uint flags; + + uint beginIndentLevel; } /// AST information that is needed by the formatter. @@ -39,6 +48,9 @@ struct ASTInformation sort(constructorDestructorLocations); sort(staticConstructorDestructorLocations); sort(sharedStaticConstructorDestructorLocations); + + sort!((a,b) => a.endLocation < b.endLocation) + (indentInfoSortedByEndLocation); } /// Locations of end braces for struct bodies @@ -92,7 +104,7 @@ struct ASTInformation /// Locations of constructor/destructor "this" tokens ? size_t[] constructorDestructorLocations; - BraceIndentInfo[] sortedByStartLocation; + BraceIndentInfo[] indentInfoSortedByEndLocation; } /// Collects information from the AST that is useful for the formatter @@ -195,8 +207,12 @@ final class FormatVisitor : ASTVisitor { if (funcLit.functionBody !is null) { - astInformation.funLitStartLocations ~= funcLit.functionBody.blockStatement.startLocation; - astInformation.funLitEndLocations ~= funcLit.functionBody.blockStatement.endLocation; + const bs = funcLit.functionBody.blockStatement; + + astInformation.funLitStartLocations ~= bs.startLocation; + astInformation.funLitEndLocations ~= bs.endLocation; + astInformation.indentInfoSortedByEndLocation ~= + BraceIndentInfo(bs.startLocation, bs.endLocation); } funcLit.accept(this); } @@ -234,6 +250,9 @@ final class FormatVisitor : ASTVisitor { astInformation.structInitStartLocations ~= structInitializer.startLocation; astInformation.structInitEndLocations ~= structInitializer.endLocation; + astInformation.indentInfoSortedByEndLocation ~= + BraceIndentInfo(structInitializer.startLocation, structInitializer.endLocation); + structInitializer.accept(this); } diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index 5d8c361..1f79181 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -737,7 +737,9 @@ private: { import std.algorithm : map, sum, canFind; - if (astInformation.structInitStartLocations.canFindIndex(tokens[index].index)) + auto tIndex = tokens[index].index; + + if (astInformation.structInitStartLocations.canFindIndex(tIndex)) { sBraceDepth++; auto e = expressionEndIndex(index); @@ -746,13 +748,21 @@ private: writeToken(); if (l > config.dfmt_soft_max_line_length) { + import std.algorithm.searching : find; + + auto indentInfo = astInformation.indentInfoSortedByEndLocation + .find!((a,b) => a.startLocation == b)(tIndex); + assert(indentInfo.length > 0); + cast()indentInfo[0].flags |= BraceIndentInfoFlags.tempIndent; + cast()indentInfo[0].beginIndentLevel = indents.indentLevel; + indents.push(tok!"{"); newline(); } else niBraceDepth++; } - else if (astInformation.funLitStartLocations.canFindIndex(tokens[index].index)) + else if (astInformation.funLitStartLocations.canFindIndex(tIndex)) { sBraceDepth++; if (peekBackIs(tok!")")) @@ -808,15 +818,34 @@ private: void formatRightBrace() { - if (astInformation.structInitEndLocations.canFindIndex(tokens[index].index)) + void popToBeginIndent(BraceIndentInfo indentInfo) + { + foreach(i; indentInfo.beginIndentLevel .. indents.indentLevel) + { + indents.pop(); + } + + indentLevel = indentInfo.beginIndentLevel; + } + + size_t pos; + if (astInformation.structInitEndLocations.canFindIndex(tokens[index].index, &pos)) { if (sBraceDepth > 0) sBraceDepth--; if (niBraceDepth > 0) niBraceDepth--; + + auto indentInfo = astInformation.indentInfoSortedByEndLocation[pos]; + if (indentInfo.flags & BraceIndentInfoFlags.tempIndent) + { + popToBeginIndent(indentInfo); + simpleNewline(); + indent(); + } writeToken(); } - else if (astInformation.funLitEndLocations.canFindIndex(tokens[index].index)) + else if (astInformation.funLitEndLocations.canFindIndex(tokens[index].index, &pos)) { if (niBraceDepth > 0) { @@ -1873,4 +1902,4 @@ bool canFindIndex(const size_t[] items, size_t index, size_t* pos = null) pure @ assert(0, "the constraint of having unique locations has been violated"); } } -} \ No newline at end of file +}