-
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
Give a specific message when analyzer references a more-recent compiler version #61261
Give a specific message when analyzer references a more-recent compiler version #61261
Conversation
src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs
Outdated
Show resolved
Hide resolved
f2f16b6
to
5554888
Compare
@@ -2099,6 +2099,8 @@ internal enum ErrorCode | |||
ERR_FixedFieldMustNotBeRef = 9049, | |||
ERR_RefFieldCannotReferToRefStruct = 9050, | |||
|
|||
WRN_AnalyzerReferencesNewerCompiler = 9057, |
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.
we're skipping error codes which we know are present in 17.4.
@@ -37,9 +38,11 @@ public enum FailureErrorCode | |||
/// </summary> | |||
public Exception? Exception { get; } | |||
|
|||
public Version? ReferencedCompilerVersion { get; init; } |
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.
The idea here was to prevent breaking the signature of the constructor, since it is public API. I guess we could use 'internal init' here as well.
Instead of adding this property, we could consider "smuggling through" a string representation of the referenced version through the 'message' property. But that is very hacky.
Ideally the public API would be much more limited here, i.e. the constructor would be internal and perhaps the entire type as well. It's not clear to me why external users would need to dig through why analyzers are failing to load instead of just surfacing the diagnostics.
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.
@mavasani do you know whether/how the IDE is directly using new AnalyzerLoadFailureEventArgs
and related APIs such as AnalyzerLoadFailureEventArgs.FailureErrorCode
?
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.
The one point I would raise is whether the increase in complexity in the API is justified by how much clearer it makes the error. Basically is the error message without this good enough? Does knowing the exact version referenced by the analyzer help the customer enough to make this API worth it? Lacking this data the customer would still have the version of the compiler and the version of the analyzer (usually it's the full path to the NuPkg).
Leaned both ways thinking about this in last 5 minutes.
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.
Lacking this data the customer would still have the version of the compiler and the version of the analyzer
The user would have the running version of the compiler, to be clear. They could be referencing an analyzer version which just happens to require a later SDK than the one they're running, and the process of figuring out manually which compiler version the analyzer is referencing may not be something we expect users to know how to do.
I'm happy to look at any way to pass along this information in a way that's found to be more palatable. But I do think the information is worth passing along.
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.
@mavasani do you know whether/how the IDE is directly using new AnalyzerLoadFailureEventArgs and related APIs such as AnalyzerLoadFailureEventArgs.FailureErrorCode?
@RikkiGibson AnalyzerLoadFailureEventArgs
is required to be exposed for all analyzer hosts that might require loading the analyzer assembly in contexts outside analyzer execution. For example, in the IDE, we need to load the analyzer assembly to populate the Analyzers
node in the solution explorer, and any failure to load the analyzer assembly needs to be reported as a diagnostic in the error list. We do so by hooking up to the event handler AnalyzerFileReference.AnalyzerLoadFailed
:
var analyzerFileReference = new AnalyzerFileReference(FullPath, s_analyzerAssemblyLoader); | |
analyzerFileReference.AnalyzerLoadFailed += OnAnalyzerLoadError; |
In the hooked up event handler, we create the appropriate diagnostic using the failure code and report it in the error list:
private void OnAnalyzerLoadError(object sender, AnalyzerLoadFailureEventArgs e) | |
{ | |
var data = DocumentAnalysisExecutor.CreateAnalyzerLoadFailureDiagnostic(e, FullPath, _projectId, _language); | |
lock (_gate) | |
{ | |
_analyzerLoadErrors = _analyzerLoadErrors.Add(data); | |
_hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(_projectId, this, _analyzerLoadErrors); | |
} | |
} |
} | ||
|
||
[ConditionalFact(typeof(IsEnglishLocal))] | ||
public void AssemblyLoading_ReferencesLaterFakeCompiler_EndToEnd_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.
I also wanted to do an end-to-end test for VB, but I wasn't able to figure out how to provide a ref to Microsoft.VisualBasic.dll and System.dll in this context. Tried a few ways of making a mock compiler.
using System; | ||
using System.Reflection; | ||
|
||
[assembly: AssemblyVersionAttribute(""42.42.42.42"")] |
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.
Why use 42.42.42.42 here? This will sometimes match the version in the MS.CA running in this process and sometimes not match it. Feels like that could lead to flakiness down the road (running unit tests on official binaries for example). My instinct says a different number should be here. Am I missing something about what this helps with?
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.
We can use a small number here. The only point of this is to be a baseline, so in the next scenario we can pinpoint the high version number as the reason it won't load. I did find that helpful when initially setting all this up though it perhaps doesn't look as helpful now that things are working :)
Looking at the failing netframework tests now. |
… fake compiler fixture.
Closes #61252
https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1569042