Initial work on #215

This commit is contained in:
Hackerpilot 2016-01-18 17:59:26 -08:00
parent 4fe021df97
commit 7fa11c8505
21 changed files with 285 additions and 4 deletions

View File

@ -19,6 +19,15 @@ enum BraceStyle
stroustrup stroustrup
} }
enum TemplateConstraintStyle
{
unspecified,
conditional_newline_indent,
conditional_newline,
always_newline,
always_newline_indent
}
/// Configuration options for formatting /// Configuration options for formatting
struct Config struct Config
{ {
@ -40,6 +49,8 @@ struct Config
OptionalBoolean dfmt_selective_import_space; OptionalBoolean dfmt_selective_import_space;
/// ///
OptionalBoolean dfmt_compact_labeled_statements; OptionalBoolean dfmt_compact_labeled_statements;
///
TemplateConstraintStyle dfmt_template_constraint_style;
mixin StandardEditorConfigFields; mixin StandardEditorConfigFields;
@ -65,6 +76,7 @@ struct Config
dfmt_split_operator_at_line_end = OptionalBoolean.f; dfmt_split_operator_at_line_end = OptionalBoolean.f;
dfmt_selective_import_space = OptionalBoolean.t; dfmt_selective_import_space = OptionalBoolean.t;
dfmt_compact_labeled_statements = OptionalBoolean.t; dfmt_compact_labeled_statements = OptionalBoolean.t;
dfmt_template_constraint_style = TemplateConstraintStyle.conditional_newline_indent;
} }
/** /**

View File

@ -491,6 +491,48 @@ private:
if (spaceAfterParens || parenDepth > 0) if (spaceAfterParens || parenDepth > 0)
write(" "); write(" ");
} }
else if (peekIs(tok!"if") && !indents.topIsTemp())
{
writeToken();
if (!peekIs(tok!"("))
return;
// assume that "if" following ")" is a template constraint
with (TemplateConstraintStyle) final switch (config.dfmt_template_constraint_style)
{
case unspecified:
assert(false, "Config was not validated properly");
case conditional_newline:
immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]);
if (l > config.dfmt_soft_max_line_length)
{
// The order of these two calls is intentional
newline();
pushWrapIndent(tok!"!");
}
else
write(" ");
break;
case always_newline:
// The order of these two calls is intentional
newline();
pushWrapIndent(tok!"!");
break;
case conditional_newline_indent:
immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]);
if (l > config.dfmt_soft_max_line_length)
{
pushWrapIndent(tok!"!");
newline();
}
else
write(" ");
break;
case always_newline_indent:
pushWrapIndent(tok!"!");
newline();
break;
}
}
else if ((peekIsKeyword() || peekIs(tok!"@")) && spaceAfterParens else if ((peekIsKeyword() || peekIs(tok!"@")) && spaceAfterParens
&& !peekIs(tok!"in") && !peekIs(tok!"is")) && !peekIs(tok!"in") && !peekIs(tok!"is"))
{ {
@ -540,7 +582,6 @@ private:
indents.push(tok!"@"); indents.push(tok!"@");
newline(); newline();
} }
} }
else if (peekBackIs(tok!"identifier") && (peekBack2Is(tok!"{", true) else if (peekBackIs(tok!"identifier") && (peekBack2Is(tok!"{", true)
|| peekBack2Is(tok!"}", true) || peekBack2Is(tok!";", true) || peekBack2Is(tok!"}", true) || peekBack2Is(tok!";", true)
@ -1352,6 +1393,8 @@ private:
formatStep(); formatStep();
} }
while (index < tokens.length && parenDepth > 0); while (index < tokens.length && parenDepth > 0);
if (indents.topIs(tok!"!"))
indents.pop();
parenDepth = depth; parenDepth = depth;
spaceAfterParens = spaceAfter; spaceAfterParens = spaceAfter;
} }

View File

@ -17,7 +17,7 @@ bool isWrapIndent(IdType type) pure nothrow @nogc @safe
} }
/** /**
* Returns: true if the given token type is a wrap indent type * Returns: true if the given token type is a temporary indent type
*/ */
bool isTempIndent(IdType type) pure nothrow @nogc @safe bool isTempIndent(IdType type) pure nothrow @nogc @safe
{ {

View File

@ -60,6 +60,7 @@ else
try try
{ {
// dfmt off
getopt(args, getopt(args,
"version", &showVersion, "version", &showVersion,
"align_switch_statements", &handleBooleans, "align_switch_statements", &handleBooleans,
@ -76,7 +77,9 @@ else
"selective_import_space", &handleBooleans, "selective_import_space", &handleBooleans,
"split_operator_at_line_end", &handleBooleans, "split_operator_at_line_end", &handleBooleans,
"compact_labeled_statements", &handleBooleans, "compact_labeled_statements", &handleBooleans,
"tab_width", &optConfig.tab_width); "tab_width", &optConfig.tab_width,
"template_constraint_style", &optConfig.dfmt_template_constraint_style);
// dfmt on
} }
catch (GetOptException e) catch (GetOptException e)
{ {
@ -207,7 +210,8 @@ Formatting Options:
--space_after_cast --space_after_cast
--selective_import_space --selective_import_space
--split_operator_at_line_end --split_operator_at_line_end
--compact_labeled_statements`); --compact_labeled_statements
--template_constraint_style `, optionsToString!(typeof(Config.dfmt_template_constraint_style))());
} }
private string createFilePath(bool readFromStdin, string fileName) private string createFilePath(bool readFromStdin, string fileName)

View File

@ -10,6 +10,28 @@ import dparse.lexer;
/// Length of an invalid token /// Length of an invalid token
enum int INVALID_TOKEN_LENGTH = -1; enum int INVALID_TOKEN_LENGTH = -1;
uint betweenParenLength(const Token[] tokens) pure @safe @nogc
in
{
assert(tokens[0].type == tok!"(");
}
body
{
uint length = 0;
size_t i = 1;
int depth = 1;
while (i < tokens.length && depth > 0)
{
if (tokens[i].type == tok!"(")
depth++;
else if (tokens[i].type == tok!")")
depth--;
length += tokenLength(tokens[i]);
i++;
}
return length;
}
int tokenLength(ref const Token t) pure @safe @nogc int tokenLength(ref const Token t) pure @safe @nogc
{ {
import std.algorithm : countUntil; import std.algorithm : countUntil;

View File

@ -0,0 +1,18 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet)
{
}
}
}

View File

@ -0,0 +1,18 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet)
{
}
}
}

View File

@ -0,0 +1,19 @@
module example;
bool aTemplatedFunction(One)(One alpha)
if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet)
{
}
}
}

View File

@ -0,0 +1,19 @@
module example;
bool aTemplatedFunction(One)(One alpha)
if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet)
{
}
}
}

1
tests/issue0215a.args Normal file
View File

@ -0,0 +1 @@
--template_constraint_style=conditional_newline_indent

15
tests/issue0215a.d Normal file
View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo && foxtrot && golf && hotel && india && juliet)
{
}
}
}

1
tests/issue0215b.args Normal file
View File

@ -0,0 +1 @@
--template_constraint_style=conditional_newline

15
tests/issue0215b.d Normal file
View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo && foxtrot && golf && hotel && india && juliet)
{
}
}
}

1
tests/issue0215c.args Normal file
View File

@ -0,0 +1 @@
--template_constraint_style=always_newline

15
tests/issue0215c.d Normal file
View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo && foxtrot && golf && hotel && india && juliet)
{
}
}
}

1
tests/issue0215d.args Normal file
View File

@ -0,0 +1 @@
--template_constraint_style=always_newline_indent

15
tests/issue0215d.d Normal file
View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One)
{
}
unittest
{
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo && foxtrot && golf && hotel && india && juliet)
{
}
}
}

View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) {
}
unittest {
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) {
}
}
}

View File

@ -0,0 +1,15 @@
module example;
bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) {
}
unittest {
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) {
}
}
}

View File

@ -0,0 +1,16 @@
module example;
bool aTemplatedFunction(One)(One alpha)
if (isNumeric!One) {
}
unittest {
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) {
}
}
}

View File

@ -0,0 +1,16 @@
module example;
bool aTemplatedFunction(One)(One alpha)
if (isNumeric!One) {
}
unittest {
{
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo,
Three charlie, double delta)
if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) {
}
}
}