-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Remove unneeded LocalizableStringWithArguments #62150
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,21 @@ namespace Microsoft.CodeAnalysis.Diagnostics | |
| { | ||
| internal static class DiagnosticHelper | ||
| { | ||
| /// <summary> | ||
| /// See InternalDiagnosticSeverity.Void. | ||
| /// </summary> | ||
| private const DiagnosticSeverity VoidSeverity = (DiagnosticSeverity)(-2); | ||
|
|
||
| private static readonly Diagnostic s_suppressedDiagnostic = Diagnostic.Create( | ||
| id: "SUPPRESSED", | ||
| category: "", | ||
| message: "", | ||
| severity: VoidSeverity, | ||
| defaultSeverity: VoidSeverity, | ||
| isEnabledByDefault: false, | ||
| warningLevel: 1, | ||
| isSuppressed: true); | ||
|
|
||
| /// <summary> | ||
| /// Creates a <see cref="Diagnostic"/> instance. | ||
| /// </summary> | ||
|
|
@@ -48,17 +63,12 @@ public static Diagnostic Create( | |
| throw new ArgumentNullException(nameof(descriptor)); | ||
| } | ||
|
|
||
| LocalizableString message; | ||
| if (messageArgs == null || messageArgs.Length == 0) | ||
| { | ||
| message = descriptor.MessageFormat; | ||
| } | ||
| else | ||
| if (effectiveSeverity == ReportDiagnostic.Suppress) | ||
| { | ||
| message = new LocalizableStringWithArguments(descriptor.MessageFormat, messageArgs); | ||
| return s_suppressedDiagnostic; | ||
| } | ||
|
|
||
| return CreateWithMessage(descriptor, location, effectiveSeverity, additionalLocations, properties, message); | ||
| return Diagnostic.Create(descriptor, location, effectiveSeverity.ToDiagnosticSeverity() ?? descriptor.DefaultSeverity, additionalLocations, properties, messageArgs); | ||
|
Comment on lines
-52
to
+72
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The public compiler API doesn't have any API that accepts message format and message arguments along with isSuppressed flag. The only API that takes isSuppressed takes a whole message. I'm using a static diagnostic that should be discarded by the compiler instead of IsSuppressed. |
||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -206,55 +216,6 @@ static string EncodeIndices(IEnumerable<int> indices, int additionalLocationsLen | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Creates a <see cref="Diagnostic"/> instance. | ||
| /// </summary> | ||
| /// <param name="descriptor">A <see cref="DiagnosticDescriptor"/> describing the diagnostic.</param> | ||
| /// <param name="location">An optional primary location of the diagnostic. If null, <see cref="Location"/> will return <see cref="Location.None"/>.</param> | ||
| /// <param name="effectiveSeverity">Effective severity of the diagnostic.</param> | ||
| /// <param name="additionalLocations"> | ||
| /// An optional set of additional locations related to the diagnostic. | ||
| /// Typically, these are locations of other items referenced in the message. | ||
| /// If null, <see cref="Diagnostic.AdditionalLocations"/> will return an empty list. | ||
| /// </param> | ||
| /// <param name="properties"> | ||
| /// An optional set of name-value pairs by means of which the analyzer that creates the diagnostic | ||
| /// can convey more detailed information to the fixer. If null, <see cref="Diagnostic.Properties"/> will return | ||
| /// <see cref="ImmutableDictionary{TKey, TValue}.Empty"/>. | ||
| /// </param> | ||
| /// <param name="message">Localizable message for the diagnostic.</param> | ||
| /// <returns>The <see cref="Diagnostic"/> instance.</returns> | ||
| public static Diagnostic CreateWithMessage( | ||
| DiagnosticDescriptor descriptor, | ||
| Location location, | ||
| ReportDiagnostic effectiveSeverity, | ||
| IEnumerable<Location>? additionalLocations, | ||
| ImmutableDictionary<string, string?>? properties, | ||
| LocalizableString message) | ||
| { | ||
| if (descriptor == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(descriptor)); | ||
| } | ||
|
|
||
| return Diagnostic.Create( | ||
| descriptor.Id, | ||
| descriptor.Category, | ||
| message, | ||
| effectiveSeverity.ToDiagnosticSeverity() ?? descriptor.DefaultSeverity, | ||
| descriptor.DefaultSeverity, | ||
| descriptor.IsEnabledByDefault, | ||
| warningLevel: effectiveSeverity.WithDefaultSeverity(descriptor.DefaultSeverity) == ReportDiagnostic.Error ? 0 : 1, | ||
| effectiveSeverity == ReportDiagnostic.Suppress, | ||
| descriptor.Title, | ||
| descriptor.Description, | ||
| descriptor.HelpLinkUri, | ||
| location, | ||
| additionalLocations, | ||
| descriptor.CustomTags, | ||
| properties); | ||
| } | ||
|
|
||
| public static string? GetHelpLinkForDiagnosticId(string id) | ||
| { | ||
| // TODO: Add documentation for Regex and Json analyzer | ||
|
|
@@ -268,90 +229,5 @@ public static Diagnostic CreateWithMessage( | |
| Debug.Assert(id.StartsWith("IDE", StringComparison.Ordinal)); | ||
| return $"https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/{id.ToLowerInvariant()}"; | ||
| } | ||
|
|
||
| public sealed class LocalizableStringWithArguments : LocalizableString, IObjectWritable | ||
| { | ||
| private readonly LocalizableString _messageFormat; | ||
| private readonly string[] _formatArguments; | ||
|
|
||
| static LocalizableStringWithArguments() | ||
| => ObjectBinder.RegisterTypeReader(typeof(LocalizableStringWithArguments), reader => new LocalizableStringWithArguments(reader)); | ||
|
|
||
| public LocalizableStringWithArguments(LocalizableString messageFormat, params object[] formatArguments) | ||
| { | ||
| if (messageFormat == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(messageFormat)); | ||
| } | ||
|
|
||
| if (formatArguments == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(formatArguments)); | ||
| } | ||
|
|
||
| _messageFormat = messageFormat; | ||
| _formatArguments = new string[formatArguments.Length]; | ||
| for (var i = 0; i < formatArguments.Length; i++) | ||
| { | ||
| _formatArguments[i] = $"{formatArguments[i]}"; | ||
| } | ||
| } | ||
|
|
||
| private LocalizableStringWithArguments(ObjectReader reader) | ||
| { | ||
| _messageFormat = (LocalizableString)reader.ReadValue(); | ||
|
|
||
| var length = reader.ReadInt32(); | ||
| if (length == 0) | ||
| { | ||
| _formatArguments = Array.Empty<string>(); | ||
| } | ||
| else | ||
| { | ||
| using var argumentsBuilderDisposer = ArrayBuilder<string>.GetInstance(length, out var argumentsBuilder); | ||
| for (var i = 0; i < length; i++) | ||
| { | ||
| argumentsBuilder.Add(reader.ReadString()); | ||
| } | ||
|
|
||
| _formatArguments = argumentsBuilder.ToArray(); | ||
| } | ||
| } | ||
|
|
||
| bool IObjectWritable.ShouldReuseInSerialization => false; | ||
|
|
||
| void IObjectWritable.WriteTo(ObjectWriter writer) | ||
| { | ||
| writer.WriteValue(_messageFormat); | ||
| var length = _formatArguments.Length; | ||
| writer.WriteInt32(length); | ||
| for (var i = 0; i < length; i++) | ||
| { | ||
| writer.WriteString(_formatArguments[i]); | ||
| } | ||
| } | ||
|
|
||
| protected override string GetText(IFormatProvider? formatProvider) | ||
| { | ||
| var messageFormat = _messageFormat.ToString(formatProvider); | ||
| return messageFormat != null ? | ||
| (_formatArguments.Length > 0 ? string.Format(formatProvider, messageFormat, _formatArguments) : messageFormat) : | ||
| string.Empty; | ||
| } | ||
|
|
||
| protected override bool AreEqual(object? other) | ||
| { | ||
| return other is LocalizableStringWithArguments otherResourceString && | ||
| _messageFormat.Equals(otherResourceString._messageFormat) && | ||
| _formatArguments.SequenceEqual(otherResourceString._formatArguments, (a, b) => a == b); | ||
| } | ||
|
|
||
| protected override int GetHash() | ||
| { | ||
| return Hash.Combine( | ||
| _messageFormat.GetHashCode(), | ||
| Hash.CombineValues(_formatArguments)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
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.
This is not correct. Even suppressed diagnostics need to be created with correct fields, such as ID, message, etc. Note that source suppressed diagnostics show up in the error list (not by default, but can be enabled by changing the filter on
Suppression Statecolumn) and can also be unsuppressed by right clicking the entry in the error list and executing theRemove Suppressioncommand.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 I thought the
(DiagnosticSeverity)(-2)will make the compiler discard the diagnostic completely inroslyn/src/Compilers/CSharp/Portable/Compilation/CSharpDiagnosticFilter.cs
Lines 60 to 63 in f7634f7
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 think we want that - suppressed diagnostics need to be present in the IDE diagnostic system for bunch of features around them to keep working.
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.
Can you point out what feature(s) need them?