mirror of
https://github.com/dlang-community/dfmt.git
synced 2025-04-25 21:00:03 +03:00
Better formatting for UFCS chains
This commit is contained in:
parent
6eb7b95173
commit
c4b9178e81
8 changed files with 63 additions and 7 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 687c0ca751747ebe498c183da1a3ee3119d57932
|
||||
Subproject commit 4f3c9ed6455cc5409c2a570576f8bd994763d652
|
|
@ -29,7 +29,8 @@ struct ASTInformation
|
|||
/// Sorts the arrays so that binary search will work on them
|
||||
void cleanup()
|
||||
{
|
||||
import std.algorithm : sort;
|
||||
import std.algorithm : sort, uniq;
|
||||
import std.array : array;
|
||||
|
||||
sort(doubleNewlineLocations);
|
||||
sort(spaceAfterLocations);
|
||||
|
@ -48,9 +49,10 @@ struct ASTInformation
|
|||
sort(constructorDestructorLocations);
|
||||
sort(staticConstructorDestructorLocations);
|
||||
sort(sharedStaticConstructorDestructorLocations);
|
||||
|
||||
sort!((a,b) => a.endLocation < b.endLocation)
|
||||
(indentInfoSortedByEndLocation);
|
||||
sort(ufcsHintLocations);
|
||||
ufcsHintLocations = ufcsHintLocations.uniq().array();
|
||||
}
|
||||
|
||||
/// Locations of end braces for struct bodies
|
||||
|
@ -104,6 +106,9 @@ struct ASTInformation
|
|||
/// Locations of constructor/destructor "this" tokens ?
|
||||
size_t[] constructorDestructorLocations;
|
||||
|
||||
/// Locations of '.' characters that might be UFCS chains.
|
||||
size_t[] ufcsHintLocations;
|
||||
|
||||
BraceIndentInfo[] indentInfoSortedByEndLocation;
|
||||
}
|
||||
|
||||
|
@ -295,6 +300,26 @@ final class FormatVisitor : ASTVisitor
|
|||
|
||||
override void visit(const UnaryExpression unary)
|
||||
{
|
||||
import std.typecons : rebindable;
|
||||
|
||||
int chainLength;
|
||||
auto u = rebindable(unary);
|
||||
while (u !is null)
|
||||
{
|
||||
if (u.identifierOrTemplateInstance !is null
|
||||
&& u.identifierOrTemplateInstance.templateInstance !is null)
|
||||
chainLength++;
|
||||
u = u.unaryExpression;
|
||||
}
|
||||
if (chainLength > 1)
|
||||
{
|
||||
u = unary;
|
||||
while (u.unaryExpression !is null)
|
||||
{
|
||||
astInformation.ufcsHintLocations ~= u.dotLocation;
|
||||
u = u.unaryExpression;
|
||||
}
|
||||
}
|
||||
if (unary.prefix.type == tok!"~" || unary.prefix.type == tok!"&"
|
||||
|| unary.prefix.type == tok!"*"
|
||||
|| unary.prefix.type == tok!"+" || unary.prefix.type == tok!"-")
|
||||
|
|
|
@ -1229,11 +1229,14 @@ private:
|
|||
break;
|
||||
case tok!".":
|
||||
regenLineBreakHintsIfNecessary(index);
|
||||
if (linebreakHints.canFind(index) || (linebreakHints.length == 0
|
||||
immutable bool ufcsWrap = astInformation.ufcsHintLocations.canFindIndex(current.index);
|
||||
if (ufcsWrap || linebreakHints.canFind(index) || (linebreakHints.length == 0
|
||||
&& currentLineLength + nextTokenLength() > config.max_line_length))
|
||||
{
|
||||
pushWrapIndent();
|
||||
newline();
|
||||
if (ufcsWrap)
|
||||
regenLineBreakHints(index);
|
||||
}
|
||||
writeToken();
|
||||
break;
|
||||
|
@ -1356,7 +1359,18 @@ private:
|
|||
|
||||
void regenLineBreakHints(immutable size_t i)
|
||||
{
|
||||
immutable size_t j = expressionEndIndex(i);
|
||||
import std.range : assumeSorted;
|
||||
import std.algorithm.comparison : min;
|
||||
import std.algorithm.searching : countUntil;
|
||||
|
||||
// The end of the tokens considered by the line break algorithm is
|
||||
// either the expression end index or the next mandatory line break,
|
||||
// whichever is first.
|
||||
auto r = assumeSorted(astInformation.ufcsHintLocations).upperBound(tokens[i].index);
|
||||
immutable ufcsBreakLocation = r.empty
|
||||
? size_t.max
|
||||
: tokens[i .. $].countUntil!(t => t.index == r.front) + i;
|
||||
immutable size_t j = min(expressionEndIndex(i), ufcsBreakLocation);
|
||||
// Use magical negative value for array literals and wrap indents
|
||||
immutable inLvl = (indents.topIsWrap() || indents.topIs(tok!"]")) ? -indentLevel
|
||||
: indentLevel;
|
||||
|
|
|
@ -3,7 +3,8 @@ unittest
|
|||
{
|
||||
{
|
||||
foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231])
|
||||
.filter!(bravo => charlie[10] > 90000).sum())
|
||||
.filter!(bravo => charlie[10] > 90000)
|
||||
.sum())
|
||||
{
|
||||
|
||||
}
|
||||
|
|
6
tests/allman/ufcschain.d.ref
Normal file
6
tests/allman/ufcschain.d.ref
Normal file
|
@ -0,0 +1,6 @@
|
|||
void main()
|
||||
{
|
||||
stuff[].map!(things => stuff.doThings)
|
||||
.filter!(stuff)
|
||||
.array();
|
||||
}
|
|
@ -2,7 +2,8 @@ unittest {
|
|||
{
|
||||
{
|
||||
foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231])
|
||||
.filter!(bravo => charlie[10] > 90000).sum()) {
|
||||
.filter!(bravo => charlie[10] > 90000)
|
||||
.sum()) {
|
||||
|
||||
}
|
||||
abcdeabcdeabcde(12341234).abcdeabcdeabcde(12341234).abcdeabcdeabcde(12341234)
|
||||
|
|
5
tests/otbs/ufcschain.d.ref
Normal file
5
tests/otbs/ufcschain.d.ref
Normal file
|
@ -0,0 +1,5 @@
|
|||
void main() {
|
||||
stuff[].map!(things => stuff.doThings)
|
||||
.filter!(stuff)
|
||||
.array();
|
||||
}
|
4
tests/ufcschain.d
Normal file
4
tests/ufcschain.d
Normal file
|
@ -0,0 +1,4 @@
|
|||
void main()
|
||||
{
|
||||
stuff[].map!(things => stuff.doThings).filter!(stuff).array();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue