Fix issue #586
This commit is contained in:
parent
35e55bc9b2
commit
1f412fe794
|
@ -52,6 +52,7 @@ found there.
|
||||||
* `--soft_max_line_length`: *see dfmt_soft_max_line_length [below](#dfmt-specific-properties)*
|
* `--soft_max_line_length`: *see dfmt_soft_max_line_length [below](#dfmt-specific-properties)*
|
||||||
* `--space_after_cast`: *see dfmt_space_after_cast [below](#dfmt-specific-properties)*
|
* `--space_after_cast`: *see dfmt_space_after_cast [below](#dfmt-specific-properties)*
|
||||||
* `--space_before_aa_colon`: *see dfmt_space_before_aa_colon [below](#dfmt-specific-properties)*
|
* `--space_before_aa_colon`: *see dfmt_space_before_aa_colon [below](#dfmt-specific-properties)*
|
||||||
|
* `--space_before_named_arg_colon`: *see dfmt_space_before_named_arg_colon [below](#dfmt-specific-properties)*
|
||||||
* `--space_before_function_parameters`: *see dfmt_space_before_function_parameters [below](#dfmt-specific-properties)*
|
* `--space_before_function_parameters`: *see dfmt_space_before_function_parameters [below](#dfmt-specific-properties)*
|
||||||
* `--split_operator_at_line_end`: *see dfmt_split_operator_at_line_end [below](#dfmt-specific-properties)*
|
* `--split_operator_at_line_end`: *see dfmt_split_operator_at_line_end [below](#dfmt-specific-properties)*
|
||||||
* `--tab_width`: *see tab_width [below](#standard-editorconfig-properties)*
|
* `--tab_width`: *see tab_width [below](#standard-editorconfig-properties)*
|
||||||
|
@ -119,6 +120,7 @@ dfmt_compact_labeled_statements | **`true`**, `false` | Place labels on the same
|
||||||
dfmt_template_constraint_style | **`conditional_newline_indent`** `conditional_newline` `always_newline` `always_newline_indent` | Control the formatting of template constraints.
|
dfmt_template_constraint_style | **`conditional_newline_indent`** `conditional_newline` `always_newline` `always_newline_indent` | Control the formatting of template constraints.
|
||||||
dfmt_single_template_constraint_indent | `true`, **`false`** | Set if the constraints are indented by a single tab instead of two. Has only an effect if the style set to `always_newline_indent` or `conditional_newline_indent`.
|
dfmt_single_template_constraint_indent | `true`, **`false`** | Set if the constraints are indented by a single tab instead of two. Has only an effect if the style set to `always_newline_indent` or `conditional_newline_indent`.
|
||||||
dfmt_space_before_aa_colon | `true`, **`false`** | Adds a space after an associative array key before the `:` like in older dfmt versions.
|
dfmt_space_before_aa_colon | `true`, **`false`** | Adds a space after an associative array key before the `:` like in older dfmt versions.
|
||||||
|
dfmt_space_before_named_arg_colon | `true`, **`false`** | Adds a space after a named function argument or named struct constructor argument before the `:`.
|
||||||
dfmt_keep_line_breaks | `true`, **`false`** | Keep existing line breaks if these don't violate other formatting rules.
|
dfmt_keep_line_breaks | `true`, **`false`** | Keep existing line breaks if these don't violate other formatting rules.
|
||||||
dfmt_single_indent | `true`, **`false`** | Set if the code in parens is indented by a single tab instead of two.
|
dfmt_single_indent | `true`, **`false`** | Set if the code in parens is indented by a single tab instead of two.
|
||||||
dfmt_reflow_property_chains | **`true`**, `false` | Recalculate the splitting of property chains into multiple lines.
|
dfmt_reflow_property_chains | **`true`**, `false` | Recalculate the splitting of property chains into multiple lines.
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct ASTInformation
|
||||||
sort(ufcsHintLocations);
|
sort(ufcsHintLocations);
|
||||||
ufcsHintLocations = ufcsHintLocations.uniq().array();
|
ufcsHintLocations = ufcsHintLocations.uniq().array();
|
||||||
sort(ternaryColonLocations);
|
sort(ternaryColonLocations);
|
||||||
|
sort(namedArgumentColonLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locations of end braces for struct bodies
|
/// Locations of end braces for struct bodies
|
||||||
|
@ -139,6 +140,9 @@ struct ASTInformation
|
||||||
|
|
||||||
/// Locations ternary expression colons.
|
/// Locations ternary expression colons.
|
||||||
size_t[] ternaryColonLocations;
|
size_t[] ternaryColonLocations;
|
||||||
|
|
||||||
|
/// Locations of named arguments of function call or struct constructor.
|
||||||
|
size_t[] namedArgumentColonLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collects information from the AST that is useful for the formatter
|
/// Collects information from the AST that is useful for the formatter
|
||||||
|
@ -448,6 +452,51 @@ final class FormatVisitor : ASTVisitor
|
||||||
ternaryExpression.accept(this);
|
ternaryExpression.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override void visit(const FunctionCallExpression functionCall)
|
||||||
|
{
|
||||||
|
// Check if function has any arguments.
|
||||||
|
if (functionCall.arguments.namedArgumentList is null)
|
||||||
|
{
|
||||||
|
functionCall.accept(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/+
|
||||||
|
Items are function arguments: f(<item>, <item>);
|
||||||
|
Iterate them and check if they are named arguments: tok!":" belongs to a
|
||||||
|
named argument if it is preceeded by one tok!"identifier" (+ any number
|
||||||
|
of comments):
|
||||||
|
+/
|
||||||
|
foreach (item; functionCall.arguments.namedArgumentList.items)
|
||||||
|
{
|
||||||
|
// Set to true after first tok!"identifier".
|
||||||
|
auto foundIdentifier = false;
|
||||||
|
|
||||||
|
foreach (t; item.tokens)
|
||||||
|
{
|
||||||
|
if (t.type == tok!"comment")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.type == tok!"identifier" && !foundIdentifier)
|
||||||
|
{
|
||||||
|
foundIdentifier = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.type == tok!":" && foundIdentifier)
|
||||||
|
{
|
||||||
|
astInformation.namedArgumentColonLocations ~= t.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
functionCall.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTInformation* astInformation;
|
ASTInformation* astInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ struct Config
|
||||||
OptionalBoolean dfmt_reflow_property_chains;
|
OptionalBoolean dfmt_reflow_property_chains;
|
||||||
///
|
///
|
||||||
OptionalBoolean dfmt_space_after_statement_keyword;
|
OptionalBoolean dfmt_space_after_statement_keyword;
|
||||||
|
///
|
||||||
|
OptionalBoolean dfmt_space_before_named_arg_colon;
|
||||||
|
|
||||||
mixin StandardEditorConfigFields;
|
mixin StandardEditorConfigFields;
|
||||||
|
|
||||||
|
@ -98,6 +100,7 @@ struct Config
|
||||||
dfmt_keep_line_breaks = OptionalBoolean.f;
|
dfmt_keep_line_breaks = OptionalBoolean.f;
|
||||||
dfmt_single_indent = OptionalBoolean.f;
|
dfmt_single_indent = OptionalBoolean.f;
|
||||||
dfmt_reflow_property_chains = OptionalBoolean.t;
|
dfmt_reflow_property_chains = OptionalBoolean.t;
|
||||||
|
dfmt_space_before_named_arg_colon = OptionalBoolean.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -835,13 +835,13 @@ private:
|
||||||
{
|
{
|
||||||
import dfmt.editorconfig : OptionalBoolean;
|
import dfmt.editorconfig : OptionalBoolean;
|
||||||
import std.algorithm : canFind, any;
|
import std.algorithm : canFind, any;
|
||||||
|
|
||||||
immutable bool isCase = astInformation.caseEndLocations.canFindIndex(current.index);
|
immutable bool isCase = astInformation.caseEndLocations.canFindIndex(current.index);
|
||||||
immutable bool isAttribute = astInformation.attributeDeclarationLines.canFindIndex(
|
immutable bool isAttribute = astInformation.attributeDeclarationLines.canFindIndex(
|
||||||
current.line);
|
current.line);
|
||||||
immutable bool isStructInitializer = astInformation.structInfoSortedByEndLocation
|
immutable bool isStructInitializer = astInformation.structInfoSortedByEndLocation
|
||||||
.canFind!(st => st.startLocation < current.index && current.index < st.endLocation);
|
.canFind!(st => st.startLocation < current.index && current.index < st.endLocation);
|
||||||
immutable bool isTernary = astInformation.ternaryColonLocations.canFindIndex(current.index);
|
immutable bool isTernary = astInformation.ternaryColonLocations.canFindIndex(current.index);
|
||||||
|
immutable bool isNamedArg = astInformation.namedArgumentColonLocations.canFindIndex(current.index);
|
||||||
|
|
||||||
if (isCase || isAttribute)
|
if (isCase || isAttribute)
|
||||||
{
|
{
|
||||||
|
@ -862,6 +862,12 @@ private:
|
||||||
write(config.dfmt_space_before_aa_colon ? " : " : ": ");
|
write(config.dfmt_space_before_aa_colon ? " : " : ": ");
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
// Named function or struct constructor arguments.
|
||||||
|
else if (isNamedArg)
|
||||||
|
{
|
||||||
|
write(config.dfmt_space_before_named_arg_colon ? " : " : ": ");
|
||||||
|
++index;
|
||||||
|
}
|
||||||
else if (peekBackIs(tok!"identifier")
|
else if (peekBackIs(tok!"identifier")
|
||||||
&& [tok!"{", tok!"}", tok!";", tok!":", tok!","]
|
&& [tok!"{", tok!"}", tok!";", tok!":", tok!","]
|
||||||
.any!((ptrdiff_t token) => peekBack2Is(cast(IdType)token, true))
|
.any!((ptrdiff_t token) => peekBack2Is(cast(IdType)token, true))
|
||||||
|
|
|
@ -92,6 +92,9 @@ else
|
||||||
case "space_before_aa_colon":
|
case "space_before_aa_colon":
|
||||||
optConfig.dfmt_space_before_aa_colon = optVal;
|
optConfig.dfmt_space_before_aa_colon = optVal;
|
||||||
break;
|
break;
|
||||||
|
case "space_before_named_arg_colon":
|
||||||
|
optConfig.dfmt_space_before_named_arg_colon = optVal;
|
||||||
|
break;
|
||||||
case "keep_line_breaks":
|
case "keep_line_breaks":
|
||||||
optConfig.dfmt_keep_line_breaks = optVal;
|
optConfig.dfmt_keep_line_breaks = optVal;
|
||||||
break;
|
break;
|
||||||
|
@ -133,6 +136,7 @@ else
|
||||||
"compact_labeled_statements", &handleBooleans,
|
"compact_labeled_statements", &handleBooleans,
|
||||||
"single_template_constraint_indent", &handleBooleans,
|
"single_template_constraint_indent", &handleBooleans,
|
||||||
"space_before_aa_colon", &handleBooleans,
|
"space_before_aa_colon", &handleBooleans,
|
||||||
|
"space_before_named_arg_colon", &handleBooleans,
|
||||||
"tab_width", &optConfig.tab_width,
|
"tab_width", &optConfig.tab_width,
|
||||||
"template_constraint_style", &optConfig.dfmt_template_constraint_style,
|
"template_constraint_style", &optConfig.dfmt_template_constraint_style,
|
||||||
"keep_line_breaks", &handleBooleans,
|
"keep_line_breaks", &handleBooleans,
|
||||||
|
@ -349,6 +353,7 @@ Formatting Options:
|
||||||
--compact_labeled_statements
|
--compact_labeled_statements
|
||||||
--template_constraint_style
|
--template_constraint_style
|
||||||
--space_before_aa_colon
|
--space_before_aa_colon
|
||||||
|
--space_before_named_arg_colon
|
||||||
--single_indent
|
--single_indent
|
||||||
--reflow_property_chains
|
--reflow_property_chains
|
||||||
`,
|
`,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
void temp(int v1, int v2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int f(int i)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
temp(v1: 1, v2: 2);
|
||||||
|
temp(v1: 1, v2: 2,);
|
||||||
|
|
||||||
|
auto s = S(5, j: 3);
|
||||||
|
|
||||||
|
temp(v1: 1, v2: f(i: 2));
|
||||||
|
|
||||||
|
temp(v1: true ? i : false ? 2 : f(i: 3), v2: 4);
|
||||||
|
|
||||||
|
temp(v1: () { S s = S(i: 5); return s.i; }, v2: 1);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
void temp(int v1, int v2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int f(int i)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
temp(v1: 1, v2: 2);
|
||||||
|
temp(
|
||||||
|
v1: 1,
|
||||||
|
v2: 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
auto s = S(5, j: 3);
|
||||||
|
|
||||||
|
temp(v1: 1, v2: f(i: 2));
|
||||||
|
|
||||||
|
temp(v1: true ? i : false ? 2 : f(i: 3), v2: 4);
|
||||||
|
|
||||||
|
temp(v1: () { S s = S(i: 5); return s.i; }, v2: 1);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
void temp(int v1, int v2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int f(int i)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
temp(v1: 1, v2: 2);
|
||||||
|
temp(v1: 1, v2: 2,);
|
||||||
|
|
||||||
|
auto s = S(5, j: 3);
|
||||||
|
|
||||||
|
temp(v1: 1, v2: f(i: 2));
|
||||||
|
|
||||||
|
temp(v1: true ? i : false ? 2 : f(i: 3), v2: 4);
|
||||||
|
|
||||||
|
temp(v1: () { S s = S(i: 5); return s.i; }, v2: 1);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
void temp(int v1, int v2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int f(int i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
temp(v1: 1, v2: 2);
|
||||||
|
temp(v1: 1, v2: 2,);
|
||||||
|
|
||||||
|
auto s = S(5, j: 3);
|
||||||
|
|
||||||
|
temp(v1: 1, v2: f(i: 2));
|
||||||
|
|
||||||
|
temp(v1: true ? i : false ? 2 : f(i: 3), v2: 4);
|
||||||
|
|
||||||
|
temp(v1: () { S s = S(i: 5); return s.i; }, v2: 1);
|
||||||
|
}
|
Loading…
Reference in New Issue