From be24f122dd7de23aac1beb81e468b946d6ddc305 Mon Sep 17 00:00:00 2001 From: Daniel Zuncke Date: Tue, 17 Oct 2023 03:49:31 +0200 Subject: [PATCH 1/3] Fix issue #432 Overview: Array astInformation.structInitEndLocations is used to find index to use in astInformation.indentInfoSortedByEndLocation. Both are sorted, first is used to find the array index, second is accessed at that index to get brace indentation information. Problem: structInitEndLocations is generated from struct initializers exclusively while the brace information array also contains entries for function literal initializers. Thus when function literal init(s) are used, we get accumulating off by one errors in the second array: match value in structInitEndLocations and take that index: [3, 50] ^--> index 1 take brace indent information from that index: [3, 15, 50] | ^--> the one we want ^------> the one we get (function literal init) Solution: This guarantees that searching forward works. While better search strategies than linear are possible, this should be enough for any sane and most of the insane code files. --- src/dfmt/formatter.d | 8 ++++++++ tests/allman/issue0432.d.ref | 17 +++++++++++++++++ tests/issue0432.d | 19 +++++++++++++++++++ tests/knr/issue0432.d.ref | 16 ++++++++++++++++ tests/otbs/issue0432.d.ref | 15 +++++++++++++++ 5 files changed, 75 insertions(+) create mode 100644 tests/allman/issue0432.d.ref create mode 100644 tests/issue0432.d create mode 100644 tests/knr/issue0432.d.ref create mode 100644 tests/otbs/issue0432.d.ref diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index 7f73ad3..f76e6e2 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -1053,6 +1053,14 @@ private: if (niBraceDepth > 0) niBraceDepth--; + // Account for possible function literals in this array which offset + // the previously set index (pos). Fixes issue #432. + while(astInformation.indentInfoSortedByEndLocation[pos].endLocation != + tokens[index].index) + { + pos++; + } + auto indentInfo = astInformation.indentInfoSortedByEndLocation[pos]; if (indentInfo.flags & BraceIndentInfoFlags.tempIndent) { diff --git a/tests/allman/issue0432.d.ref b/tests/allman/issue0432.d.ref new file mode 100644 index 0000000..fde6383 --- /dev/null +++ b/tests/allman/issue0432.d.ref @@ -0,0 +1,17 @@ +struct S +{ + ulong x; + ulong y; + ulong z; + ulong w; +} + +immutable int function(int) f = (x) { return x + 1111; }; + +immutable S s = { + 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, +}; + +void main() +{ +} diff --git a/tests/issue0432.d b/tests/issue0432.d new file mode 100644 index 0000000..9140425 --- /dev/null +++ b/tests/issue0432.d @@ -0,0 +1,19 @@ +struct S +{ + ulong x; + ulong y; + ulong z; + ulong w; +} + +immutable int function(int) f = (x) { return x + 1111; }; + +immutable S s = { + 1111111111111111111, + 1111111111111111111, + 1111111111111111111, + 1111111111111111111,}; + + void main() + { + } diff --git a/tests/knr/issue0432.d.ref b/tests/knr/issue0432.d.ref new file mode 100644 index 0000000..9f54651 --- /dev/null +++ b/tests/knr/issue0432.d.ref @@ -0,0 +1,16 @@ +struct S { + ulong x; + ulong y; + ulong z; + ulong w; +} + +immutable int function(int) f = (x) { return x + 1111; }; + +immutable S s = { + 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, +}; + +void main() +{ +} diff --git a/tests/otbs/issue0432.d.ref b/tests/otbs/issue0432.d.ref new file mode 100644 index 0000000..81cae57 --- /dev/null +++ b/tests/otbs/issue0432.d.ref @@ -0,0 +1,15 @@ +struct S { + ulong x; + ulong y; + ulong z; + ulong w; +} + +immutable int function(int) f = (x) { return x + 1111; }; + +immutable S s = { + 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, +}; + +void main() { +} From 979c74d0d0b15d332019d55d0de727899b208777 Mon Sep 17 00:00:00 2001 From: Daniel Zuncke Date: Tue, 17 Oct 2023 17:56:22 +0200 Subject: [PATCH 2/3] Update test to include both known cases I have formatted them both to look like the the individual bad output and not like the actual output from formatting the issue0432.d file with the current implementation. The current implementation makes it look like a new / different problem. --- tests/allman/issue0432.d.ref | 31 +++++++++++++++++++++++++++---- tests/issue0432.d | 35 +++++++++++++++++++++++++++-------- tests/knr/issue0432.d.ref | 30 ++++++++++++++++++++++++++---- tests/otbs/issue0432.d.ref | 29 +++++++++++++++++++++++++---- 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/tests/allman/issue0432.d.ref b/tests/allman/issue0432.d.ref index fde6383..9edb2d9 100644 --- a/tests/allman/issue0432.d.ref +++ b/tests/allman/issue0432.d.ref @@ -1,4 +1,11 @@ -struct S +struct S1 +{ + ulong x; + ulong y; + ulong function(ulong) f; +} + +struct S2 { ulong x; ulong y; @@ -6,12 +13,28 @@ struct S ulong w; } -immutable int function(int) f = (x) { return x + 1111; }; +// ----------------------------------------------------------------------------- +// Example 1 +// Anonymous function in struct, long struct initializer + +immutable S1 s1 = { + 1111111111111111111, 1111111111111111111, (x) { return x + 1111; }, +}; + +void f1() +{ +} + +// ----------------------------------------------------------------------------- +// Example 2 +// Anonymous function anywhere, long struct initializer + +int function(int) f2 = (x) { return x + 1111; }; -immutable S s = { +immutable S2 s = { 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, }; -void main() +void f2() { } diff --git a/tests/issue0432.d b/tests/issue0432.d index 9140425..bbaa2bb 100644 --- a/tests/issue0432.d +++ b/tests/issue0432.d @@ -1,4 +1,11 @@ -struct S +struct S1 +{ + ulong x; + ulong y; + ulong function(ulong)f; +} + +struct S2 { ulong x; ulong y; @@ -6,14 +13,26 @@ struct S ulong w; } -immutable int function(int) f = (x) { return x + 1111; }; +// ----------------------------------------------------------------------------- +// Example 1 +// Anonymous function in struct, long struct initializer + +immutable S1 s1 = { + 1111111111111111111, 1111111111111111111, (x) { return x + 1111; },}; + + void f1() + { + } + +// ----------------------------------------------------------------------------- +// Example 2 +// Anonymous function anywhere, long struct initializer + +int function(int) f2 = (x) { return x + 1111; }; -immutable S s = { - 1111111111111111111, - 1111111111111111111, - 1111111111111111111, - 1111111111111111111,}; +immutable S2 s = { + 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111,}; - void main() + void f2() { } diff --git a/tests/knr/issue0432.d.ref b/tests/knr/issue0432.d.ref index 9f54651..f403c86 100644 --- a/tests/knr/issue0432.d.ref +++ b/tests/knr/issue0432.d.ref @@ -1,16 +1,38 @@ -struct S { +struct S1 { + ulong x; + ulong y; + ulong function(ulong) f; +} + +struct S2 { ulong x; ulong y; ulong z; ulong w; } -immutable int function(int) f = (x) { return x + 1111; }; +// ----------------------------------------------------------------------------- +// Example 1 +// Anonymous function in struct, long struct initializer + +immutable S1 s1 = { + 1111111111111111111, 1111111111111111111, (x) { return x + 1111; }, +}; + +void f1() +{ +} + +// ----------------------------------------------------------------------------- +// Example 2 +// Anonymous function anywhere, long struct initializer + +int function(int) f2 = (x) { return x + 1111; }; -immutable S s = { +immutable S2 s = { 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, }; -void main() +void f2() { } diff --git a/tests/otbs/issue0432.d.ref b/tests/otbs/issue0432.d.ref index 81cae57..4690082 100644 --- a/tests/otbs/issue0432.d.ref +++ b/tests/otbs/issue0432.d.ref @@ -1,15 +1,36 @@ -struct S { +struct S1 { + ulong x; + ulong y; + ulong function(ulong) f; +} + +struct S2 { ulong x; ulong y; ulong z; ulong w; } -immutable int function(int) f = (x) { return x + 1111; }; +// ----------------------------------------------------------------------------- +// Example 1 +// Anonymous function in struct, long struct initializer + +immutable S1 s1 = { + 1111111111111111111, 1111111111111111111, (x) { return x + 1111; }, +}; + +void f1() { +} + +// ----------------------------------------------------------------------------- +// Example 2 +// Anonymous function anywhere, long struct initializer + +int function(int) f2 = (x) { return x + 1111; }; -immutable S s = { +immutable S2 s = { 1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111, }; -void main() { +void f2() { } From 4a0841745a9804139c808d88777e4c344ef5908e Mon Sep 17 00:00:00 2001 From: Daniel Zuncke Date: Tue, 17 Oct 2023 20:24:02 +0200 Subject: [PATCH 3/3] Confirm token equality, safer loop Using different variable to iterate to guarantee unchanged behaviour if anything doesn't work as intended. --- src/dfmt/formatter.d | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index f76e6e2..8ea8cc6 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -1055,10 +1055,17 @@ private: // Account for possible function literals in this array which offset // the previously set index (pos). Fixes issue #432. - while(astInformation.indentInfoSortedByEndLocation[pos].endLocation != + size_t newPos = pos; + while(astInformation.indentInfoSortedByEndLocation[newPos].endLocation < tokens[index].index) { - pos++; + newPos++; + } + + if (astInformation.indentInfoSortedByEndLocation[newPos].endLocation == + tokens[index].index) + { + pos = newPos; } auto indentInfo = astInformation.indentInfoSortedByEndLocation[pos];