CodeConverter icon indicating copy to clipboard operation
CodeConverter copied to clipboard

VB -> C#: #if conditional compilation preprocessor directives are not converted

Open Yozer opened this issue 3 years ago • 3 comments

VB.Net input code

#If Debug
        Console.WriteLine("A")
#Else
        Console.WriteLine("B")
#End If

Erroneous output

/* TODO ERROR: Skipped IfDirectiveTrivia
#If Debug
*/
Console.WriteLine("A");
/* TODO ERROR: Skipped ElseDirectiveTrivia
#Else
*//* TODO ERROR: Skipped DisabledTextTrivia
        Console.WriteLine("B")
*//* TODO ERROR: Skipped EndIfDirectiveTrivia
#End If
*/

Expected output

#if DEBUG
    Console.WriteLine("A");
#else
    Console.WriteLine("B");
#endif

Details

  • Product in use: e.g. codeconverter.icsharpcode.net / VS extension / both
  • Version in use: e.g. 5.6.3 or a commit hash 69a16a7bb0af66c511c2493d4e5e771f90bff439
  • Did you see it working in a previous version, which?
  • Any other relevant information to the issue, or your interest in contributing a fix.

Yozer avatar Apr 03 '22 16:04 Yozer

Yep this is a tricky one. Though obviously the current situation could definitely be improved. I'll dedupe with this one https://github.com/icsharpcode/CodeConverter/issues/15#issuecomment-374409309

GrahamTheCoder avatar Apr 04 '22 08:04 GrahamTheCoder

I would like to work on this, but I am kind of stuck. I figured out that it is probably here somewhere things need to be changed: https://github.com/icsharpcode/CodeConverter/blob/2314120b93818eb1041b3145cf6d57824f6df677/CodeConverter/Util/SyntaxNodeExtensions.cs#L375-L433

The problem is that the code inside the #if-Block is passed as a DisabledTextTrivia token and not converted at all and I cannot figure out how to prevent this.

Alternatively one could do it like @chtenb suggested here https://github.com/icsharpcode/CodeConverter/issues/15#issuecomment-777427251 and do some pre and postprocessing on the input and output text instead of the syntax tree, because this might be easier. You can basically do these replacements:

  • #If ... Then => #if ...
  • #Else => #else
  • #ElseIf ... => #elif ...
  • #End If => #endif
  • And => &, etc.

And then hope for the best. 😄 There might still be rare cases where this is not enough, but I suppose this would handle most cases pretty well. At least better than at the moment.

As I said I would like to start on this, but I don't know where the best place to put this kind pre- and postprocessing would be. Can you point me in the right direction?

Sympatron avatar Oct 18 '23 10:10 Sympatron

In terms of the directive itself, a bit of replacement might work, but for the contents proper parsing is needed. Might be easiest initially to use the top level conversion api on the text, which already detects various types of snippet: https://github.com/icsharpcode/CodeConverter/blob/2314120b93818eb1041b3145cf6d57824f6df677/CodeConverter/Common/ProjectConversion.cs#L35 Just hack it in at first and see if it provides useful results for real world examples. If not, we'll probably need to provide the whole file with the conditional directives removed. We could do that as a pre processing step then add them back as post processing. Some such processing already happens to rename clashing names. https://github.com/icsharpcode/CodeConverter/blob/2314120b93818eb1041b3145cf6d57824f6df677/CodeConverter/CSharp/ClashingMemberRenamer.cs

GrahamTheCoder avatar Oct 18 '23 22:10 GrahamTheCoder