vblang
vblang copied to clipboard
Question: Should analyzers for VB.NET be written in VB.NET?
Pro C#:
- Wider pool of potential maintainers (but see point 4)
- Pattern matching (as of this writing)
- Extending an existing analyzer (but see point 5)
Pro VB.NET
- VB.NET programmers are more familiar with the language, and are thus better suited to write and maintain an analyzer.
- Analyzers don't really lend themselves to cross-language extension -- the Roslyn
SyntaxKindenums and the syntax node classes are different between languages.
The specific analyzer that I want to write for VB.NET already exists for C# here, with a request for VB.NET support.
The only guidance I was able to find specifically about writing analyzers/code fixes for VB.NET (by @AnthonyDGreen) describes writing them in VB.NET.
ping @AnthonyDGreen @bandleader @KathleenDollard
I don't think the language would matter much, but doing it in VB would be better because as you say, the person will be familiar with language's structure and in the rare case they want to contribute, they can do so in a familiar language.
I don't come across analyzers very much in my coding environment but code fixes/refactorings I use very heavily and would most likely contribute to some if they were done in VB for VB.
The general reasons I see for these sort of things not supporting VB is because the maintainers don't understand VB or don't have experience in VB. So if they don't understand the language well enough to write code in VB, then I don't see how they'd be able to navigate the syntax tree and know about all of the possible node types. Which really means there's only one possible answer to your question - yes, VB analyzers should be written in VB.
The roslyn analyzers seem to have tackled this problem by having a base class that the C# and VB implementations inherit from. I can't speak for how effective this is though, because, other than just looking around in the codebase, I haven't actually tried to do anything with that code. Here's an example:
- Base class: UseNameofInPlaceOfString
- C# implementation, written in C#: CSharpUseNameofInPlaceOfString VB implementation, written in VB: BasicUseNameofInPlaceOfString
And there's even some analyzers that don't require language-specific implementations because they handle both C# and VB. For example, DoNotRaiseExceptionsInExceptionClauses. Don't ask me how they do it though! 😁
I seem to recall reading something about language-agnostic analyzers quite some time ago, but can't remember where I might have read that. @gafter (apologies if you're the wrong person to ask), have there ever been plans to make it easier to develop an analyzer for both C# and VB code?
@reduckted It's interesting to note that even in the UseNameofInPlaceOfString analyzer, the only language-specific parts are to figure out if NameOf exists in the current version.
' VB.NET
' https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeQuality.Analyzers/VisualBasic/Maintainability/BasicUseNameofInPlaceOfString.vb
Protected Overrides Function IsApplicableToLanguageVersion(options As ParseOptions) As Boolean
Return CType(options, VisualBasicParseOptions).LanguageVersion >= LanguageVersion.VisualBasic14
End Function
// C#
// https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeQuality.Analyzers/CSharp/Maintainability/CSharpUseNameofInPlaceOfString.cs
protected override bool IsApplicableToLanguageVersion(ParseOptions options) {
return (((CSharpParseOptions)options).LanguageVersion >= LanguageVersion.CSharp6);
}
The actual logic for the analyzer and the code fix is shared across languages.
@reduckted From .NET Compiler Platform - Language-Agnostic Code Generation with Roslyn:
You can use the Roslyn APIs and the
SyntaxGeneratorclass whenever you need to perform rich analysis over source code, but this approach is also very useful with analyzers and code refactorings. In fact, analyzers, code fixes, and refactorings have theDiagnosticAnalyzer,ExportCodeFixProvider, andExportCodeRefactoringProviderattributes, respectively, each accepting the primary and secondary supported languages. By usingSyntaxGeneratorinstead ofSyntaxFactory, you can target both C# and Visual Basic simultaneously.
Is this what you meant?
(NB. I've read it a few times by now, but I'm still not sure how to apply it.)
I have written several refactoring and would love to contribute but have no idea how to even start (where are they added , who approved which ones people want, are they part of Roslyn or somewhere else).
The one I think is most useful adds or removes type information from Declares, based on Option settings. They are all written in VB though I do depend on one C# module to deal with Hash that I just cloned out of Roslyn. I have been able to process all of Roslyn if you don't mind waiting a few hours I have not updated the recently so I don't know if performance is improved with newer Roslyn libraries.
Dim X = 1
' Becomes
Dim X as Integer = 1
' Becomes
Dim X = 1
@paul1956 The directions here seem straightforward. The 'Analyzer with code fix" template produces a .vsix, which can then be published to the Marketplace as described here. Once you upload to the Marketplace, your analyzer will be available to anyone to install into VS.
Alternatively, since the template creates a .NET Standard DLL, you can upload it as a Nuget package, as described here. Then, anyone can add your analyzer to their project as a NuGet reference.
(NB. I haven't actually tried either of these; I'm still trying to wrap my head around writing the analyzer code.)
@zspitz So these are not open source on GitHub? I have written both the VSIX kind and NuGet package you get both from the template, don't know how the NuGet one helps anyone. Right now my VSIX has 20+ VB analyzers/Codefixes all written in VB but some are only interesting to me or are available from others like code-cracker, would I just package the one that does the adding and removing Types from DIm statements and Function/Sub declarations?
@paul1956
these are not open source on GitHub
I'm not sure what you mean. You don't have to publish your analyzer to GitHub or any other open-source repository. If it's only for your personal use, then you may not need to publish it at all; just add a reference to the built DLL.
But I think other people could use the analyzer you're describing, so you might want to consider packaging it separately and publishing it.
don't know how the NuGet one helps anyone
If I'm not mistaken, once it's in a NuGet package, you can either add it to a local feed, or upload to nuget.org. Then, it can be found by using the NuGet package management in VS (in the case of a local feed, you have to add the local feed).
The analyzer will then be available to any project that references it, but only to that project.
If you want it available to every project, then it needs to be packaged as a VSIX.
I am attempting to write an Analyzer/CodeFixProvider in C# for VB (pattern matching is awesome, although I think #172 would have worked just as well if I was writing vb), and while I can run and debug the analyzer, I am unable to get the CodeFixProvider to be executed when debugging (haven’t tried it in a non-debug session yet).
When trying to add the vb nuget packages for code analysis it looked like it was restricting the choices to c# packages somehow, had to do things manually once before I could get the vb dll’s for the analyzer.
Got it working, but don’t know exactly what the problem was, (I think either namespaces or name of classes)
My guidance from CyrusNajmabadi on the linked question was to use VB for a vb Analyzer.
Yes. In general roslyn writes vb analyzers/fixers in VB. Though if we write something for both c# and vb then we'll usually extract all the shared logic into code in a common lib.