From 495d6d9f7e3caaca68b560948d6bc903d2793536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= Date: Sat, 4 Jul 2026 05:15:58 +0300 Subject: [PATCH] Fix comment to be after `extern (C):` Currently code like this ```c #define G1 #ifdef G1 // Guard1 #define A 1 #else #define A 2 #endif #ifdef G2 // Guard2 #define B 3 #else #define B 4 #endif ``` Produces: ```d extern (C): // Guard1 enum A = 1; // Guard2 enum B = 4; ``` Notice how `Guard1` comment is in same line as `extern (C):` which looks wrong. This commit fixes this issue so that it's on a new line like `Guard2`. --- dstep/translator/Output.d | 20 +++++++++++++++++--- tests/unit/CommentUnitTests.d | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/dstep/translator/Output.d b/dstep/translator/Output.d index 0fb36bfd..c1f8d591 100644 --- a/dstep/translator/Output.d +++ b/dstep/translator/Output.d @@ -218,6 +218,7 @@ class Output private uint lastestOffset = 0; private uint lastestLine = 0; + private uint lastContentLine = 0; private uint headerEndOffset = 0; this(Output parent) @@ -231,6 +232,7 @@ class Output commentIndex = parent.commentIndex; lastestOffset = parent.lastestOffset; lastestLine = parent.lastestLine; + lastContentLine = parent.lastContentLine; } this( @@ -268,6 +270,7 @@ class Output lastestOffset = 0; lastestLine = 0; + lastContentLine = 0; headerEndOffset = 0; } @@ -325,6 +328,7 @@ class Output lastestOffset = max(lastestOffset, output.lastestOffset); lastestLine = max(lastestLine, output.lastestLine); + lastContentLine = max(lastContentLine, output.lastContentLine); } } @@ -348,6 +352,7 @@ class Output indent(); formattedWrite(buffer, fmt, args); stack.back = Entity.singleLine; + lastContentLine = lastestLine; if (first == Entity.bottom) first = Entity.singleLine; @@ -469,6 +474,8 @@ class Output if (first == Entity.bottom) first = Entity.adaptiveLine; + lastContentLine = lastestLine; + auto parts = adaptiveLineParts(fmt, args); chunks.put(Chunk(ChunkType.opening, parts[0], parts[1])); @@ -715,13 +722,17 @@ D"[0 .. $ - 1]); } } } + + lastContentLine = comment.extent.end.line; } private void comment(in CommentIndex.Comment comment) { - if (lastestLine == comment.line) + auto wasInline = false; + if (lastContentLine == comment.line) { buffer.put(" "); + wasInline = true; } else if (stack.back != Entity.bottom) { @@ -736,11 +747,14 @@ D"[0 .. $ - 1]); writeComment(comment); - stack.back = Entity.comment; - if (first == Entity.bottom) first = Entity.comment; + if (!wasInline && lastestLine == comment.extent.end.line) + stack.back = Entity.separator; + else + stack.back = Entity.comment; + lastestLine = comment.extent.end.line; lastestOffset = comment.extent.end.offset; } diff --git a/tests/unit/CommentUnitTests.d b/tests/unit/CommentUnitTests.d index d7ec906d..df1ed360 100644 --- a/tests/unit/CommentUnitTests.d +++ b/tests/unit/CommentUnitTests.d @@ -339,3 +339,35 @@ struct Foo D"); } + +// Comment inside taken #ifdef branch must not join extern (C): line. +unittest +{ + assertTranslates( +q"C +#define G1 + +#ifdef G1 // Guard1 +#define A 1 +#else +#define A 2 +#endif + +#ifdef G2 // Guard2 +#define B 3 +#else +#define B 4 +#endif +C", +q"D +extern (C): + +// Guard1 + +enum A = 1; + +// Guard2 + +enum B = 4; +D", true); +}