dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
290 stars 64 forks source link

VB Source Generator example #586

Open paul1956 opened 3 years ago

paul1956 commented 3 years ago

Could we have some VB examples for VB Source Generators that demonstrate "you could just use SourceGenerators to .. automatically". I have no problem with issues being closed with that as an answer as it allows the community to solve their possibly niche issues themselves except that 1) VB Does not yet have Source Generators (in production) 2) There is no VB documentation on how to access them in preview 3) There are no examples of using them in VB

Feel free to move this to Documentation repo if that is where is belongs.

VBAndCs commented 3 years ago

@DualBrain published some: https://github.com/DualBrain/Samples/tree/master/SourceGenerators

DualBrain commented 3 years ago

I also submitted it to roslyn-sdk samples over at https://github.com/dotnet/roslyn-sdk/pull/691

Apparently I screwed up the pull request because I assumed there would be a git ignore associated; so have to rebase and resubmit (which, off the top of my head, I'm not familiar with - so willing to spend the time to figure it out... but...). In any case, at least one team member thinks that it might not be "valuable"; so either way... it's available through my Samples repo. ;-)

paul1956 commented 3 years ago

@DualBrain I noticed you use ZIP to start. You need to fork Repo on GitHub, then clone in Visual Studio so you have a private copy, then Push to your GitHub account, then branch in Visual Studio (so you are working in isolation). VS will handle all the Git stuff for you.

DualBrain commented 3 years ago

I did fork... but the problem may be that I used github to create the pull request instead of Visual Studio. Never tried doing that directly in VS so I'll have to explore that further. In any case, I resubmitted the samples making sure that the files the didn't desire were not included.

sharwell commented 3 years ago

I think I figured out a balance that will work. Instead of setting a goal of porting all the current examples, we could come up with a set of "hello world" style examples that cover the basics of creating a VB source generator without getting too deep into the generated code itself. The approach assumes developers have an idea of what the generated code will look like, but aren't familiar with the process of creating, configuring, and packaging the generator.

DualBrain commented 3 years ago

The thing is that I've learned a ton from all of the examples on the road to producing the one that I'm actually interested in pursuing. If, for example, the only example was the CSV one... I would have been left stumbling around in the dark trying to figure out "where do I go from here". It's a great example, but wouldn't have helped me in any way on the road to "getting started" for what I'm trying to accomplish. That doesn't mean it's not valuable.. it certainly is. I actually do a lot of stuff with CSV files... and, as it happens, I wouldn't have even considered leveraging code generation to improve the process of handling CSV files without the inspiration of this very example. As it turns out, the example that most closely fit what I was trying to accomplish is the AutoNotifyGenerator example. Without it, I don't think I could have gotten where I've gotten to so far. If the HelloWorldGenerator was the only one available... I suspect the technology would have been something that I'd been left with no real choice then to simply "move on". With all of the samples, a very different story. The biggest problem with all of these being in C# only is that there are a lot of "modern" concepts leveraged in C# that simply have no counterpart in VB. Even converting all of the code, I'm still left with one warning that I'm left scratching my head wondering how to get rid of the stinking warning. The code is working, but that damned warning is sitting down there at the bottom of my Visual Studio window taunting me... telling me I'm an idiot. ;-)

Specifically, the following:

  For Each group In fieldSymbols.GroupBy(Function(f) f.ContainingType)
    Dim classSource = ProcessClass(group.Key, group.ToList(), attributeSymbol, notifySymbol)
    context.AddSource($"{group.Key.Name}_AutoNotify.vb", SourceText.From(classSource, Encoding.UTF8))
  Next

The warning is on the For Each telling me:

"Compare symbols correctly."

As I was typing this up, I decided to try to take another stab at it using VB-style Linq...

After some fiddling, settled on:

  For Each entry In From p In fieldSymbols Group p By Key = p.ContainingType.Name, Type = p.ContainingType Into Group
    Dim classSource = ProcessClass(entry.Type, entry.Group.ToList(), attributeSymbol, notifySymbol)
    context.AddSource($"{entry.Key}_AutoNotify.vb", SourceText.From(classSource, Encoding.UTF8))
  Next

Although it's possible to get rid of the warning using this method; still bugs me that the original requires such a big jump (literally and conceptually) to what seems should be a simple conversion.

It's things like this that continue to disappoint me regarding not having samples in a way that is more easily consumed. The idea that people can "simply" read C# and convert it to VB is simply not valid... and is becoming less and less valid as time progresses with C# apparently on a mission to become the next PERL. It is becoming harder and harder to read as the version number increases given the overwhelming desire to type less-and-less characters to the point that {}_=>a is meaningful. It's wonderful and all that shortcuts like this exist for C# devs reading C# code, but in what world is it reasonable to expect VB devs to grock this random stuff?. Deciphering samples leveraging the latest and greatest C# feature is, in many cases, just simply not worth the effort for the majority of VB developers in the world.

Now if all samples were written in a hamstrung manner so that the code is "readable regardless of language choice"... then sure. However, is that really fair to C# devs? With that said, I do question "throwing everything and the kitchen sink" concepts into samples that distract from the core technology concept being presented. In other words, to understand a sample you have to stop (as a C# dev) to go look up pattern matching, records, tuple deconstruction, etc. just to following along to learn about the Source Generator feature.

On the bright side... apparently us VB devs don't have to worry about this problem as (if they exist) any examples for new technology can focus on the technology being discussed and not be overwhelmed with yet more changes to the language. ;-)

craigajohnson commented 3 years ago

I think I figured out a balance that will work. Instead of setting a goal of porting all the current examples, we could come up with a set of "hello world" style examples that cover the basics of creating a VB source generator without getting too deep into the generated code itself. The approach assumes developers have an idea of what the generated code will look like, but aren't familiar with the process of creating, configuring, and packaging the generator.

A couple of Hello World examples would be great. Working for me but had to look at a couple of .csproj files to see the necessary annotations to the project reference.

Nukepayload2 commented 3 years ago

I'm trying to write a MyWpfExtension.vb generator for .NET Core and .NET 5 projects. https://github.com/Nukepayload2/MyWpfExtensionGenerator But I noticed that the generated code can't be used by early binding code in WPF projects. I don't know how to solve this problem.

VBAndCs commented 3 years ago

Try to separate the generated code in a different project then the code that uses it. In general, this is a good n-Tier practice, but it is not always easy. Sometimes, you need a VS.NET extension to generate the code you want just when you save the code file, like what happens when you use a form designer, or entities designer.

paul1956 commented 3 years ago

One of the example is to use Code Generation instead of the designer to handle settings that is what you want.

DualBrain commented 2 years ago

Circling back to this with an update... there is another example of leveraging a Source Generator to enhance VB so it supports an Implicit Interfaces experience.

Please note that although the current nuget and/or sample definitely work, improvements could certainly take place by leveraging Roslyn code generation features instead of its current text-only implementation.