-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Do not load CodeStyle analyzers added by the SDK #75250
Do not load CodeStyle analyzers added by the SDK #75250
Conversation
return OneOrMany.Create(fullPath); | ||
} | ||
|
||
private static readonly string s_csharpCodeStyleAnalyzerSdkDirectory = Path.Combine("Sdks", "Microsoft.NET.Sdk", "codestyle", "cs") + PathUtilities.DirectorySeparatorStr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
if (Language == LanguageNames.VisualBasic && | ||
fullPath.LastIndexOf(s_visualBasicCodeStyleAnalyzerSdkDirectory, StringComparison.OrdinalIgnoreCase) + s_visualBasicCodeStyleAnalyzerSdkDirectory.Length - 1 == | ||
fullPath.LastIndexOf(Path.DirectorySeparatorChar)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this would be a bit easier to read as a separate fn since it's done in 3 places
return OneOrMany.Create(fullPath); | ||
} | ||
|
||
private static readonly string s_csharpCodeStyleAnalyzerSdkDirectory = Path.Combine("Sdks", "Microsoft.NET.Sdk", "codestyle", "cs") + PathUtilities.DirectorySeparatorStr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Should we just look at the assembly name? With the current approach, if users explicitly reference a version of the code style package instead of using the one in the SDK, they will end up in the same bad IDE state we have today. The other option is to just stop shipping the code style layer as a separate package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thus far we've tried to limit this to when you load the analyzer / generator from the .NET SDK. The idea being that we want to isolate the .NET SDK from being able to negatively influence Visual Studio behavior. But our sample size is one, Razor, and there is no package option for that.
The guidance we're trying to give to 3rd party package is they need to be aware of the VS versions they can be loaded in and multi-target analyze for that.
My recommendation is start with the change as is, let's see if we get negative feedback and we can adjust based on that.
Note that this will load the analyzers which ship in the IDE, but it does not correct the error where the wrong options are provided to those analyzers (analyzers in the IDE use values from Tools > Options, but those same analyzers in a build do not). |
return OneOrMany.Create(fullPath); | ||
} | ||
|
||
private static readonly string s_csharpCodeStyleAnalyzerSdkDirectory = Path.Combine("Sdks", "Microsoft.NET.Sdk", "codestyle", "cs") + PathUtilities.DirectorySeparatorStr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thus far we've tried to limit this to when you load the analyzer / generator from the .NET SDK. The idea being that we want to isolate the .NET SDK from being able to negatively influence Visual Studio behavior. But our sample size is one, Razor, and there is no package option for that.
The guidance we're trying to give to 3rd party package is they need to be aware of the VS versions they can be loaded in and multi-target analyze for that.
My recommendation is start with the change as is, let's see if we get negative feedback and we can adjust based on that.
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.Fixes.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes.dll")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all of these DLLs already in box that we're mapping to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably needs VB too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the in box code style analyzers. We are ensuring that they do not get returned as AnalyzerReferences from the Project. Which means they will not be used for analysis.
} | ||
|
||
return OneOrMany<string>.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My one fear is that this is hard to test in a unit test. Do we have an item on the queue to do manual verification of Razor / Code style once this is all merged in?
Have we thought about adding an integration test that verifies we redirected these loads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be easy enough to write an integration test for this. Will do as a follow up after the snap.
Do we have a design-time target somewhere we can add a hack in that removes these at the MSBuild level instead? This is a perfectly fine tactical fix of course, but that'd avoid side effects like this. |
src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs
Show resolved
Hide resolved
src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/AnalyzerReferenceTests.vb
Outdated
Show resolved
Hide resolved
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.Fixes.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes.dll")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do resource binaries get added too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe resource binaries are added as AnalyzerReferences to the project. I would expect they are loaded by the AnalyzerAssemblyLoader.
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CodeStyle.Fixes.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.dll")) | ||
project.AddAnalyzerReference(Path.Combine(TempRoot.Root, "Sdks", "Microsoft.NET.Sdk", "codestyle", "cs", "Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes.dll")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably needs VB too.
|
||
private bool IsSdkCodeStyleAnalyzer(string fullPath) | ||
{ | ||
if (Language == LanguageNames.CSharp && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to just match on Sdks\Microsoft.NET.Sdk\codestyle and work for both languages at once?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to make that change. Didn't have a good feel with how specific we wanted to get.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually will keep it as is. The code currently checks for the analyzer path to end with the folder path fragment which is a stronger guarantee than just containing the fragment.
src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/AnalyzerReferenceTests.vb
Outdated
Show resolved
Hide resolved
{ | ||
// We discard the CodeStyle analyzers added by the SDK when the EnforceCodeStyleInBuild property is set. | ||
// The same analyzers ship in-box as part of the Features layer and are version matched to the compiler. | ||
return OneOrMany<string>.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to call it out explicitly, doing this here will:
- Also apply to VS Code (which might be reasonable since we'll have similar issues there I imagine)
- Will not apply to MSBuildWorkspace, which might be bad, or might not be.
The latter we can of course defer for this change (since this has huge dogfooding benefit), but wanted to call out the former.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't love that we're expanding this mechanism, given the work we're doing to allow the SDK to redirect analyzers via #74820
That isn't a reason to block on this, given its not done yet, but could we open an issue to investigate if we could replace this with the new API when it's introduced?
} | ||
|
||
return OneOrMany.Create(fullPath); | ||
} | ||
|
||
private static string CreateDirectoryPathFragment(params string[] paths) => Path.Combine([" ", .. paths, " "]).Trim(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So Path.Combine will add the separator then we trim it off the spaces. Was just trying to put the work onto Path.Combine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is dumb. Happy to revert it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely not dumb, just a little too tricky for me to spot without the explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am going to do a follow up that adds an integration test. Will add a comment here as well.
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
0ca4cb7
to
71bec2e
Compare
@JoeRobich quick question: will it work if the paths to analyzers contain I haven't tried in VS, but some other hosts receive paths like this: I haven't checked whether the VS project system normalizes paths before this codepath is hit. |
Thanks for checking! We do call roslyn/src/Workspaces/Core/Portable/Workspace/ProjectSystem/ProjectSystemProject.cs Lines 1033 to 1037 in 3bff362
|
To avoid a version mismatch between the version of Roslyn in the IDE and the version of Roslyn CodeStyle analyzers added by the SDK (#72811), we will not load the CodeStyle analyzers added by the SDK. The IDE ships with the same analyzers which are version matched and used during analysis.
The analyzers are still listed in the Solution Explorer but without any associated analyzers.