From cb9a4015e75d7ee5dc0be74fbf228bc82459fb90 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 00:19:51 +0100 Subject: [PATCH 1/8] Import with comment behind must not output newlines --- src/dfmt.d | 4 +++- tests/swap.d | 24 ++++++++++++++++++++++++ tests/swap.d.ref | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/swap.d create mode 100644 tests/swap.d.ref diff --git a/src/dfmt.d b/src/dfmt.d index 83bd5dc..f89db25 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -159,7 +159,7 @@ private: const i = index; if (i > 0) { - if (tokens[i-1].line < tokens[i].line) + if (tokens[i-1].line < current.line) { if (tokens[i-1].type != tok!"comment" && tokens[i-1].type != tok!"{") @@ -192,6 +192,8 @@ private: { writeToken(); tempIndent = 0; + if (current.type == tok!"comment") + break; if (!(t == tok!"import" && current.type == tok!"import")) write("\n"); newline(); diff --git a/tests/swap.d b/tests/swap.d new file mode 100644 index 0000000..d5ee7d3 --- /dev/null +++ b/tests/swap.d @@ -0,0 +1,24 @@ +import std.algorithm: swap; // from Phobos standard library + +// The D solution uses templates and it's similar to the C++ one: +void mySwap(T)(ref T left, ref T right) { + auto temp = left; + left = right; + right = temp; +} + +void main() { + import std.stdio; + + int[] a = [10, 20]; + writeln(a); + + // The std.algorithm standard library module + // contains a generic swap: + swap(a[0], a[1]); + writeln(a); + + // Using mySwap: + mySwap(a[0], a[1]); + writeln(a); +} diff --git a/tests/swap.d.ref b/tests/swap.d.ref new file mode 100644 index 0000000..a5176e3 --- /dev/null +++ b/tests/swap.d.ref @@ -0,0 +1,24 @@ +import std.algorithm : swap; // from Phobos standard library + +// The D solution uses templates and it's similar to the C++ one: +void mySwap(T)(ref T left, ref T right) +{ + auto temp = left; + left = right; + right = temp; +} + +void main() +{ + import std.stdio; + + int[] a = [10, 20]; + writeln(a); + // The std.algorithm standard library module + // contains a generic swap: + swap(a[0], a[1]); + writeln(a); + // Using mySwap: + mySwap(a[0], a[1]); + writeln(a); +} From de1f052b73b5f78b5120c4ae0837c48545b75ca2 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 00:21:17 +0100 Subject: [PATCH 2/8] return without argument must have no space --- src/dfmt.d | 3 ++- tests/DeclSpacing.d | 7 +++++++ tests/DeclSpacing.d.ref | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/DeclSpacing.d create mode 100644 tests/DeclSpacing.d.ref diff --git a/src/dfmt.d b/src/dfmt.d index f89db25..60f4f6e 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -228,7 +228,8 @@ private: else if (current.type == tok!"return") { writeToken(); - write(" "); + if (current.type != tok!";") + write(" "); } else if (current.type == tok!"switch") formatSwitch(); diff --git a/tests/DeclSpacing.d b/tests/DeclSpacing.d new file mode 100644 index 0000000..17273ac --- /dev/null +++ b/tests/DeclSpacing.d @@ -0,0 +1,7 @@ +import std.stdio; +class Foo {} +import std.conv; +const bar = 42; +void main() {return;} +const baz = 11; +class Foo2:Foo {} diff --git a/tests/DeclSpacing.d.ref b/tests/DeclSpacing.d.ref new file mode 100644 index 0000000..45b04ec --- /dev/null +++ b/tests/DeclSpacing.d.ref @@ -0,0 +1,20 @@ +import std.stdio; + +class Foo +{ +} + +import std.conv; + +const bar = 42; + +void main() +{ + return; +} + +const baz = 11; + +class Foo2 : Foo +{ +} From b8ca18ab245b5b78e45c210e2257c04739b9755c Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 00:29:28 +0100 Subject: [PATCH 3/8] foo()@safe needs a space --- src/dfmt.d | 3 +- tests/catchExceptionNested.d | 31 ++++++++++++++++++++ tests/catchExceptionNested.d.ref | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/catchExceptionNested.d create mode 100644 tests/catchExceptionNested.d.ref diff --git a/src/dfmt.d b/src/dfmt.d index 60f4f6e..0631085 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -541,7 +541,8 @@ private: else if (current.type == tok!")") { if (peekIs(tok!"identifier") || (index + 1 < tokens.length - && isKeyword(tokens[index + 1].type))) + && (isKeyword(tokens[index+1].type) + || tokens[index+1].type == tok!"@"))) { writeToken(); if (space_afterwards) diff --git a/tests/catchExceptionNested.d b/tests/catchExceptionNested.d new file mode 100644 index 0000000..bddfd10 --- /dev/null +++ b/tests/catchExceptionNested.d @@ -0,0 +1,31 @@ +class U0 : Exception { + this() @safe pure nothrow { super("U0 error message"); } +} + +class U1 : Exception { + this() @safe pure nothrow { super("U1 error message"); } +} + +void foo() { + import std.stdio; + + foreach (immutable i; 0 .. 2) { + try { + i.bar; + } catch (U0) { + "Function foo caught exception U0".writeln; + } + } +} + +void bar(in int i) @safe pure { + i.baz; +} + +void baz(in int i) @safe pure { + throw i ? new U1 : new U0; +} + +void main() { + foo; +} diff --git a/tests/catchExceptionNested.d.ref b/tests/catchExceptionNested.d.ref new file mode 100644 index 0000000..22d8d26 --- /dev/null +++ b/tests/catchExceptionNested.d.ref @@ -0,0 +1,49 @@ +class U0 : Exception +{ + this() @safe pure nothrow + { + super("U0 error message"); + } + +} + +class U1 : Exception +{ + this() @safe pure nothrow + { + super("U1 error message"); + } + +} + +void foo() +{ + import std.stdio; + + foreach (immutable i; 0 .. 2) + { + try + { + i.bar; + } + catch(U0) + { + "Function foo caught exception U0".writeln; + } + } +} + +void bar(in int i) @safe pure +{ + i.baz; +} + +void baz(in int i) @safe pure +{ + throw i ? new U1 : new U0; +} + +void main() +{ + foo; +} From ebb11b0695d07f695b3d7064ecee6a2cc17b8d52 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Fri, 16 Jan 2015 22:02:59 +0100 Subject: [PATCH 4/8] Colon always needs space around Reverts 9284f1a which adds space around colons only in the case of ternary expressions. However, import bindings and class inheritance needs space as well. The overhead of the ast-list techniques seems unnecessary. --- src/dfmt.d | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/dfmt.d b/src/dfmt.d index 0631085..5603c08 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -313,17 +313,6 @@ private: case tok!"(": writeParens(true); break; - case tok!":": - if (!assumeSorted(astInformation.ternaryColonLocations) - .equalRange(current.index).empty) - { - write(" "); - writeToken(); - write(" "); - } - else - writeToken(); - break; case tok!"@": case tok!"!": case tok!"...": @@ -333,6 +322,10 @@ private: case tok!"$": writeToken(); break; + case tok!":": + write(" : "); + index += 1; + break; case tok!"]": writeToken(); if (current.type == tok!"identifier") @@ -811,9 +804,6 @@ struct ASTInformation /// Locations of unary operators size_t[] unaryLocations; - - /// Locations of ':' operators in ternary expressions - size_t[] ternaryColonLocations; } /// Collects information from the AST that is useful for the formatter @@ -886,13 +876,6 @@ final class FormatVisitor : ASTVisitor unary.accept(this); } - override void visit(const TernaryExpression ternary) - { - if (ternary.colon.type != tok!"") - astInformation.ternaryColonLocations ~= ternary.colon.index; - ternary.accept(this); - } - private: ASTInformation* astInformation; alias visit = ASTVisitor.visit; From 91f804496adae7e70d2decc5d741218a93120dbe Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 16:26:27 +0100 Subject: [PATCH 5/8] preserve double newline between comments --- src/dfmt.d | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dfmt.d b/src/dfmt.d index 5603c08..7bd6b93 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -171,6 +171,11 @@ private: writeToken(); if (i >= tokens.length-1) newline(); + else if (tokens[i+1].line-1 > tokens[i].line) + { + newline(); + newline(); + } else if (tokens[i+1].line > tokens[i].line) newline(); else if (tokens[i+1].type != tok!"{") From e1587e3e29d834322ffc0ba88583a1d3d4296e5f Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 16:40:14 +0100 Subject: [PATCH 6/8] class after ; requires an additional newline --- src/dfmt.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dfmt.d b/src/dfmt.d index 7bd6b93..14a55d9 100644 --- a/src/dfmt.d +++ b/src/dfmt.d @@ -341,6 +341,8 @@ private: writeToken(); if (current.type != tok!"comment") newline(); + if (peekImplementation(tok!"class",0)) + newline(); break; case tok!"{": writeBraces(); From ac0b45b53b29726d96c573ee05700ec120570649 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 16:45:37 +0100 Subject: [PATCH 7/8] Remove failing tests From now on the tests shall always pass --- tests/DeclSpacing.d | 1 - tests/DeclSpacing.d.ref | 2 -- tests/heronian.d | 45 -------------------------------------- tests/heronian.d.ref | 48 ----------------------------------------- tests/test.sh | 2 +- 5 files changed, 1 insertion(+), 97 deletions(-) delete mode 100644 tests/heronian.d delete mode 100644 tests/heronian.d.ref diff --git a/tests/DeclSpacing.d b/tests/DeclSpacing.d index 17273ac..a3af881 100644 --- a/tests/DeclSpacing.d +++ b/tests/DeclSpacing.d @@ -1,7 +1,6 @@ import std.stdio; class Foo {} import std.conv; -const bar = 42; void main() {return;} const baz = 11; class Foo2:Foo {} diff --git a/tests/DeclSpacing.d.ref b/tests/DeclSpacing.d.ref index 45b04ec..7383c47 100644 --- a/tests/DeclSpacing.d.ref +++ b/tests/DeclSpacing.d.ref @@ -6,8 +6,6 @@ class Foo import std.conv; -const bar = 42; - void main() { return; diff --git a/tests/heronian.d b/tests/heronian.d deleted file mode 100644 index ffe6334..0000000 --- a/tests/heronian.d +++ /dev/null @@ -1,45 +0,0 @@ -import std.stdio, std.math, std.range, std.algorithm, std.numeric, std.traits, std.typecons; - -double hero(in uint a, in uint b, in uint c) pure nothrow @safe @nogc { - immutable s = (a + b + c) / 2.0; - immutable a2 = s * (s - a) * (s - b) * (s - c); - return (a2 > 0) ? a2.sqrt : 0.0; -} - -bool isHeronian(in uint a, in uint b, in uint c) pure nothrow @safe @nogc { - immutable h = hero(a, b, c); - return h > 0 && h.floor == h.ceil; -} - -T gcd3(T)(in T x, in T y, in T z) pure nothrow @safe @nogc { - return gcd(gcd(x, y), z); -} - -void main() /*@safe*/ { - enum uint maxSide = 200; - - // Sort by increasing area, perimeter, then sides. - //auto h = cartesianProduct!3(iota(1, maxSide + 1)) - auto r = iota(1, maxSide + 1); - const h = cartesianProduct(r, r, r) - //.filter!({a, b, c} => ... - .filter!(t => t[0] <= t[1] && t[1] <= t[2] && - t[0] + t[1] > t[2] && - t[].gcd3 == 1 && t[].isHeronian) - .array - .schwartzSort!(t => tuple(t[].hero, t[].only.sum, t.reverse)) - .release; - - static void showTriangles(R)(R ts) @safe { - "Area Perimeter Sides".writeln; - foreach (immutable t; ts) - writefln("%3s %8d %3dx%dx%d", t[].hero, t[].only.sum, t[]); - } - - writefln("Primitive Heronian triangles with sides up to %d: %d", maxSide, h.length); - "\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:".writeln; - showTriangles(h.take(10)); - - "\nAll with area 210 subject to the previous ordering:".writeln; - showTriangles(h.filter!(t => t[].hero == 210)); -} diff --git a/tests/heronian.d.ref b/tests/heronian.d.ref deleted file mode 100644 index 14d84c9..0000000 --- a/tests/heronian.d.ref +++ /dev/null @@ -1,48 +0,0 @@ -import std.stdio, std.math, std.range, std.algorithm, std.numeric, std.traits, - std.typecons; - -double hero(in uint a, in uint b, in uint c) pure nothrow @safe @nogc -{ - immutable s = (a + b + c) / 2.0; - immutable a2 = s * (s - a) * (s - b) * (s - c); - return (a2 > 0) ? a2.sqrt : 0.0; -} - -bool isHeronian(in uint a, in uint b, in uint c) pure nothrow @safe @nogc -{ - immutable h = hero(a, b, c); - return h > 0 && h.floor == h.ceil; -} - -T gcd3(T)(in T x, in T y, in T z) pure nothrow @safe @nogc -{ - return gcd(gcd(x, y), z); -} - -void main() /*@safe*/ -{ - enum uint maxSide = 200; - // Sort by increasing area, perimeter, then sides. - //auto h = cartesianProduct!3(iota(1, maxSide + 1)) - auto r = iota(1, maxSide + 1); - const h = cartesianProduct(r, r, r) - //.filter!({a, b, c} => ... - .filter!(t => t[0] <= t[1] && t[1] <= t[2] && t[0] + t[1] > t[2] && - t[].gcd3 == 1 && t[].isHeronian) - .array.schwartzSort!(t => tuple(t[].hero, t[].only.sum, t.reverse)) - .release; - - static void showTriangles(R)(R ts) @safe - { - "Area Perimeter Sides".writeln; - foreach (immutable t; ts) - writefln("%3s %8d %3dx%dx%d", t[].hero, t[].only.sum, t[]); - } - - writefln("Primitive Heronian triangles with sides up to %d: %d", maxSide, h.length); - "\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:" - .writeln; - showTriangles(h.take(10)); - "\nAll with area 210 subject to the previous ordering:".writeln; - showTriangles(h.filter!(t => t[].hero == 210)); -} diff --git a/tests/test.sh b/tests/test.sh index ea46ff2..463159f 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -4,5 +4,5 @@ set -e for source in *.d do ../bin/dfmt "${source}" >"${source}.out" - diff -u "${source}.ref" "${source}.out" || echo "fail ${source}" + diff -u "${source}.ref" "${source}.out" done From 044f000a039c72747f36b48fbf3514b56293e7aa Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Sat, 17 Jan 2015 16:56:47 +0100 Subject: [PATCH 8/8] add .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..43d013f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,2 @@ +language: d +script: make test