Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB -> C#: Inline 'My' name space - special VB winforms generated code #169

Closed
ghost opened this issue Aug 22, 2018 · 5 comments · Fixed by #387
Closed

VB -> C#: Inline 'My' name space - special VB winforms generated code #169

ghost opened this issue Aug 22, 2018 · 5 comments · Fixed by #387
Assignees
Labels
VB -> C# Specific to VB -> C# conversion

Comments

@ghost
Copy link

ghost commented Aug 22, 2018

Covers all issues converting 'My' namespace


I created a simple VB WinForms app (simple = 1 form with 1 button, and the button just creates a MsgBox which says hello). After installing the package, and converting the project, it would not build.

Please help?

All files, and screenshots of each step of the process were uploaded to GitHub, and can be found here:

https://github.com/GregoryMattingly/VB_To_CSharp

I was / tried to be very thorough with my documentation; please email me if you have questions.

Thank You in advance,

@GrahamTheCoder GrahamTheCoder changed the title "VB -> C#" VB -> C#: Better winforms conversion Aug 24, 2018
@GrahamTheCoder GrahamTheCoder added the VB -> C# Specific to VB -> C# conversion label Aug 24, 2018
@GrahamTheCoder
Copy link
Member

Thanks for getting in touch. I've now removed this from the "known issues" since it's covered by this issue. But it used to say "Waiting for user request: Better support for converting the autogenerated winforms code". I'll consider this a user request.

In general it is possible to convert huge amounts of code with relatively few errors using this converter, though it's rare to get 0 errors. Unfortunately Winforms VB generates all classes which heavily use special internal compiler types that don't exist in C# - most of it is in the "My" namespace.

So there are basically three options:

  1. Inline all the vb compiler internal implementation into the converted solution
  2. Create a nuget package containing all the Microsoft internal code, but with the public modifier, then update all references to point at that.
  3. Do a close approximation that has different behaviour but is standard .NET code.

Since no-one asked for it until now, I just haven't bother trying to solve this problem, hence it's pretty much the worst aspect of the converter.

From where you are in your project, the simplest thing to decrease errors is to add a reference to the assembly Microsoft.VisualBasic. That of course might have been nice for the converter to do automatically. After that you'll find you have a class MyApplication which looks suspiciously like it's missing a base class. It is, the VB compiler would have inlined it into your assembly at compile time.

Any thoughts on which of the 3 options you might have expected?

@ghost
Copy link
Author

ghost commented Aug 24, 2018 via email

@GrahamTheCoder
Copy link
Member

GrahamTheCoder commented Aug 24, 2018

Sorry I wasn't very clear. Adding the reference to visual basic is the step you can do right now - you'll then see some different errors. You will find those errors are currently reasonably tricky to deal with - the code is a faithful conversion, but since you'll now be using the c# compiler, the vb compiler won't be there to do the special transformation that makes it all work in vb usually.

To avoid these errors, ideally I'll need to do work to add some code inlining/injection to the converter (essentially doing what the vb compiler would generate or transform, but in c#) . I think I'm most inclined to pick the nuget option providing that the license of the compiler code will allow me to do so. The down side of nuget is that the web converter won't be able to add the reference - but it could add a comment to tell you to do so, and avoiding adding more code to the target project seems sensible. However, I may take a combined approach since some of the code generated depends on the project.
I can't really give a time frame since it's hard work to get right and I haven't investigated enough yet. Hope that makes sense.

@GrahamTheCoder GrahamTheCoder changed the title VB -> C#: Better winforms conversion VB -> C#: Inline special VB winforms generated code Jul 21, 2019
@GrahamTheCoder GrahamTheCoder changed the title VB -> C#: Inline special VB winforms generated code VB -> C#: Inline 'My' name space - special VB winforms generated code Jul 31, 2019
@GrahamTheCoder
Copy link
Member

GrahamTheCoder commented Aug 16, 2019

I've now made a _csCompliation field available for the VB assembly, which should allow iterating over declarations in the My name space and generating an outline at least. To get things compiling, the converter could make everything could throw and be marked obsolete. We can iterate from there to work for common cases

It's actually possible to get the VB syntax tree by looking at the Global namespace's "MergedDeclaration" property. e.g.
_compilation.SourceModule.GlobalNamespace

We might be able to get at the details without reflection by using something like Locations which accesses the internal property :
https://github.com/dotnet/roslyn/blob/faf86e81de60b7ae76d5f754a2aaf92d89b403d1/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs#L88

They're thousands of lines long, but it might be worth invoking the converter on them anyway as a first effort. They include a lot of compile time preprocessor symbols/commands, but Roslyn should be able to resolve those at parse time and give the relevant syntax tree.

@GrahamTheCoder GrahamTheCoder self-assigned this Sep 22, 2019
@GrahamTheCoder
Copy link
Member

GrahamTheCoder commented Oct 6, 2019

I've made some progress on this and can now (a5a261b) directly convert the template code that the compiler embeds. This gives the basic outline for statically generated code. However, there are two further levels of complexity I'm aware of that aren't covered by this static template since they're project dependent:

  • There is a property generated per Form and per WebService in the My namespace. Getting the logic for these to match exactly the compiler's might be tricky, so finding a way to enumerate all such symbols (which have no syntax references or location), and use their methods that directly output VB strings would be a good approach if it can be done with reasonably little reflection.
  • There is special handling of accesses to those properties which would need to be emulated by updating the usages at conversion time. This code is too tied to the completely internal BoundExpression API, so will need to be essentially duplicated working against the Symbol/Operation API.

So we're pretty much going to:

  1. Look for all the synthesized properties in the relevant classes, and output a partial class with a field+property for each one but with a modified name instead of WinformsDesignerTest:
      [EditorBrowsable(EditorBrowsableState.Never)]
      public WinformsDesignerTest m_WinformsDesignerTest;

      public WinformsDesignerTest WinformsDesignerTest
      {
        [DebuggerHidden] get
        {
          this.m_WinformsDesignerTest = MyProject.MyForms.Create__Instance__<WinformsDesignerTest>(this.m_WinformsDesignerTest);
          return this.m_WinformsDesignerTest;
        }
        [DebuggerHidden] set
        {
          if (value == this.m_WinformsDesignerTest)
            return;
          if (value != null)
            throw new ArgumentException("Property can only be set to Nothing");
          this.Dispose__Instance__<WinformsDesignerTest>(ref this.m_WinformsDesignerTest);
        }
      }
  1. Modify VisitBinaryExpression for the Is and IsNot operators to dig through conversions/casts and replace property accesses where IsMyGroupCollectionProperty with IPropertySymbol.AssociatedField.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
VB -> C# Specific to VB -> C# conversion
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant