Skip to content

Remove unneeded LocalizableStringWithArguments#62150

Closed
Youssef1313 wants to merge 3 commits intodotnet:mainfrom
Youssef1313:localizable-string-with-arg
Closed

Remove unneeded LocalizableStringWithArguments#62150
Youssef1313 wants to merge 3 commits intodotnet:mainfrom
Youssef1313:localizable-string-with-arg

Conversation

@Youssef1313
Copy link
Member

No description provided.

@ghost ghost added Community The pull request was submitted by a contributor who is not a Microsoft employee. Area-IDE labels Jun 27, 2022
@Youssef1313
Copy link
Member Author

@mavasani Can you take a look please?

Comment on lines 52 to 71
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);
Copy link
Member Author

Choose a reason for hiding this comment

The 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.

if (effectiveSeverity == ReportDiagnostic.Suppress)
{
message = new LocalizableStringWithArguments(descriptor.MessageFormat, messageArgs);
return s_suppressedDiagnostic;
Copy link
Contributor

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 State column) and can also be unsuppressed by right clicking the entry in the error list and executing the Remove Suppression command.

Copy link
Member Author

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 in

else if (d.Severity == InternalDiagnosticSeverity.Void)
{
return null;
}

Copy link
Contributor

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.

Copy link
Member Author

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?

@mavasani
Copy link
Contributor

@Youssef1313 Can you please clarify the motivation behind this change? I don't see any trivial simplification/code cleanup/bug fix happening in this PR, so am really keen on knowing why you feel this change is better than the current implementation.

@Youssef1313
Copy link
Member Author

Youssef1313 commented Jun 27, 2022

@mavasani Most important thing is IsSuppressed documentation mentions attribute/pragma suppression, but this code path has nothing to do with that. So we're passing an incorrect value of IsSuppressed.

Also as you mentioned in #62150 (comment), such diagnostics can show in error list. The correct behavior in my opinion is to avoid showing them at all, which (hopefully) is achieved by using -2 for the severity (I haven't yet confirmed if it works that way)

@mavasani
Copy link
Contributor

The intention here was to avoid showing them by using -2 for the severity (I haven't yet confirmed if it works that way)

Why would we want to avoid showing them in the error list? Suppressed diagnostics should should up in the error list when the Suppression State column filter has been modified to allow showing suppressed diagnostics.

image

image

@Youssef1313
Copy link
Member Author

@mavasani The thing is that they're not source suppressed. If I understand correctly, the IDE should show suppressions that are done in source (attribute or pragma). The current use of isSuppress violates its documentation if I understand correctly.

/// <summary>
/// Returns true if the diagnostic has a source suppression, i.e. an attribute or a pragma suppression.
/// </summary>
public abstract bool IsSuppressed { get; }

@mavasani
Copy link
Contributor

The thing is that they're not source suppressed

Ah, that is indeed correct. However, I don't think the approach chosen here will work. An analyzer wouldn't be allowed to report a diagnostic with an ID outside the set of IDs in its SupportedDiagnsotics, so I believe as soon as the analyzer tries to invoke context.ReportDiagnostic for the newly added suppressed diagnostic, the driver will throw an AD0001.

@mavasani
Copy link
Contributor

I think the correct approach is either to change the DiagnosticHelper.Create API to return a potentially null result, and analyzer handles and skips null diagnostics OR add a DiagnosticHelper.CreateAndReportDiagnostic method that does this to avoid every analyzer from having to do the null check.

@Youssef1313
Copy link
Member Author

I wanted to make that with minimal changes as possible. But I'll switch to the CreateAndReportDiagnostic suggestion.

I partially did that in the last commit. Remaining is some callsites. Can you review the general approach before I fix all callsites? Thanks!

@Youssef1313
Copy link
Member Author

@mavasani Can you check if the approach taken now is good enough? It requires modifying all analyzers (unfortunately).

@Youssef1313
Copy link
Member Author

Youssef1313 commented Jul 2, 2022

Another idea that may avoid too many changes is something similar to:

struct DiagnosticWrapper
{
    Diagnostic diagnostic;
}

class DiagnosticHelper
{
    // all create methods return a DiagnosticWrapper that potentially has a null diagnostic.
}

static class DiagnosticExtensions
{
    // this will be repeated for all available analysis context types.
    public static void ReportDiagnostic(this Context context, DiagnosticWrapper wrapper)
    {
        if (wrapper.diagnostic is not null) context.ReportDiagnostic(wrapper.diagnostic);
    }
}

@Youssef1313
Copy link
Member Author

I'll open a new PR with the approach I mentioned in the previous comment. If it's not the preferred approach, I'll re-open this PR and work on it.

@Youssef1313 Youssef1313 closed this Jul 8, 2022
@Youssef1313 Youssef1313 deleted the localizable-string-with-arg branch July 8, 2022 07:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants