mirror of
https://github.com/dlang-community/dfmt.git
synced 2025-04-29 06:39:55 +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
|
/// Sorts the arrays so that binary search will work on them
|
||||||
void cleanup()
|
void cleanup()
|
||||||
{
|
{
|
||||||
import std.algorithm : sort;
|
import std.algorithm : sort, uniq;
|
||||||
|
import std.array : array;
|
||||||
|
|
||||||
sort(doubleNewlineLocations);
|
sort(doubleNewlineLocations);
|
||||||
sort(spaceAfterLocations);
|
sort(spaceAfterLocations);
|
||||||
|
@ -48,9 +49,10 @@ struct ASTInformation
|
||||||
sort(constructorDestructorLocations);
|
sort(constructorDestructorLocations);
|
||||||
sort(staticConstructorDestructorLocations);
|
sort(staticConstructorDestructorLocations);
|
||||||
sort(sharedStaticConstructorDestructorLocations);
|
sort(sharedStaticConstructorDestructorLocations);
|
||||||
|
|
||||||
sort!((a,b) => a.endLocation < b.endLocation)
|
sort!((a,b) => a.endLocation < b.endLocation)
|
||||||
(indentInfoSortedByEndLocation);
|
(indentInfoSortedByEndLocation);
|
||||||
|
sort(ufcsHintLocations);
|
||||||
|
ufcsHintLocations = ufcsHintLocations.uniq().array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locations of end braces for struct bodies
|
/// Locations of end braces for struct bodies
|
||||||
|
@ -104,6 +106,9 @@ struct ASTInformation
|
||||||
/// Locations of constructor/destructor "this" tokens ?
|
/// Locations of constructor/destructor "this" tokens ?
|
||||||
size_t[] constructorDestructorLocations;
|
size_t[] constructorDestructorLocations;
|
||||||
|
|
||||||
|
/// Locations of '.' characters that might be UFCS chains.
|
||||||
|
size_t[] ufcsHintLocations;
|
||||||
|
|
||||||
BraceIndentInfo[] indentInfoSortedByEndLocation;
|
BraceIndentInfo[] indentInfoSortedByEndLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +300,26 @@ final class FormatVisitor : ASTVisitor
|
||||||
|
|
||||||
override void visit(const UnaryExpression unary)
|
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!"&"
|
if (unary.prefix.type == tok!"~" || unary.prefix.type == tok!"&"
|
||||||
|| unary.prefix.type == tok!"*"
|
|| 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;
|
break;
|
||||||
case tok!".":
|
case tok!".":
|
||||||
regenLineBreakHintsIfNecessary(index);
|
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))
|
&& currentLineLength + nextTokenLength() > config.max_line_length))
|
||||||
{
|
{
|
||||||
pushWrapIndent();
|
pushWrapIndent();
|
||||||
newline();
|
newline();
|
||||||
|
if (ufcsWrap)
|
||||||
|
regenLineBreakHints(index);
|
||||||
}
|
}
|
||||||
writeToken();
|
writeToken();
|
||||||
break;
|
break;
|
||||||
|
@ -1356,7 +1359,18 @@ private:
|
||||||
|
|
||||||
void regenLineBreakHints(immutable size_t i)
|
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
|
// Use magical negative value for array literals and wrap indents
|
||||||
immutable inLvl = (indents.topIsWrap() || indents.topIs(tok!"]")) ? -indentLevel
|
immutable inLvl = (indents.topIsWrap() || indents.topIs(tok!"]")) ? -indentLevel
|
||||||
: indentLevel;
|
: indentLevel;
|
||||||
|
|
|
@ -3,7 +3,8 @@ unittest
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231])
|
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])
|
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)
|
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