Conversation
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Analyzers/AnalyzerResources.resx
Outdated
Show resolved
Hide resolved
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
- Use symbols rather than syntax - Only report if both parameter and editor required are on the property - Thread through the cancellation token
|
Ok, updated to use symbols. Will work on adding some tests if we're happy with this approach. |
333fred
left a comment
There was a problem hiding this comment.
Think this is in a good enough place to go for the tests.
| @@ -1,4 +1,4 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
There was a problem hiding this comment.
Looks like it was missing the BOM and this adds it back.
| if (attributes.Any(ad => SymbolEqualityComparer.Default.Equals(ad.AttributeClass, parameterSymbol)) | ||
| && attributes.Any(ad => SymbolEqualityComparer.Default.Equals(ad.AttributeClass, editorRequiredSymbol))) |
There was a problem hiding this comment.
Nit: cute syntax, but potentially loops through the list twice. Maybe a foreach would be better 🙂.
- remove XunitVerifiers and use default verifier instead (see https://github.com/dotnet/roslyn-sdk/blob/main/src/Microsoft.CodeAnalysis.Testing/README.md#obsolete-packages) - Remove uneeded .xunit package references
| using System; | ||
| using Microsoft.AspNetCore.Components; | ||
|
|
||
| public class MyComponent |
There was a problem hiding this comment.
This test makes me wonder. Should we be checking that these attributes are being used in something that implements IComponent?
There was a problem hiding this comment.
I don't think that's required, consider this example:
abstract class B
{
[Parameter, EditorRequired] string Param { get; set; }
}
class C : B, IComponent;B doesn't implement IComponent but can still be instantiated as a component through C.
There was a problem hiding this comment.
IMO, for this type of edge case, I'd prefer to have false positives, rather than false negatives (iow, I think we should check for implementing IComponent). If we get feedback that this case is still being hit and causing pain, then we can take another look at it.
There was a problem hiding this comment.
Yeah, lets keep it tightly scoped for now, and we can expand it later if we get feedback on it
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Show resolved
Hide resolved
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Outdated
Show resolved
Hide resolved
| using System; | ||
| using Microsoft.AspNetCore.Components; | ||
|
|
||
| public class MyComponent |
There was a problem hiding this comment.
I don't think that's required, consider this example:
abstract class B
{
[Parameter, EditorRequired] string Param { get; set; }
}
class C : B, IComponent;B doesn't implement IComponent but can still be instantiated as a component through C.
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
|
|
||
| public override void ReportSuppressions(SuppressionAnalysisContext context) | ||
| { | ||
| var editorRequiredSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.EditorRequiredAttribute"); |
There was a problem hiding this comment.
Couple Qs:
- Should we bail out of the analyzer here if the value is
null? - This will fail in the face of multiple definitions of this type. Not against that but want to make sure we clearly decided this.
There was a problem hiding this comment.
Added an early return if we can't find the types, and a test to show behavior in the presence of duplicate attributes.
| public override void ReportSuppressions(SuppressionAnalysisContext context) | ||
| { | ||
| var editorRequiredSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.EditorRequiredAttribute"); | ||
| var parameterSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.ParameterAttribute"); |
There was a problem hiding this comment.
Should we bail out if this is null?
Ensure the parameter is well defined
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Outdated
Show resolved
Hide resolved
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Outdated
Show resolved
Hide resolved
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Outdated
Show resolved
Hide resolved
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Outdated
Show resolved
Hide resolved
| public class MyComponent : ComponentBase | ||
| { | ||
| [Parameter, EditorRequired] | ||
| public string MyParameter { get; set; } |
There was a problem hiding this comment.
Consider also testing string?.
| } | ||
|
|
||
| [Theory] | ||
| [InlineData("init;")] |
There was a problem hiding this comment.
It looks like the runtime supports init parameters just fine, so perhaps we should suppress the warning for them as well?
There was a problem hiding this comment.
So it turns out this already supported init properties, this test just wasn't explicitly checking IsSuppressed(false) so it was incorrectly passing. I've added an explicit suppress check for all the instances where it should be false and split init out into its own passing test.
...oft.NET.Sdk.Razor.SourceGenerators.Tests/ComponentParameterNullableWarningSuppressorTests.cs
Show resolved
Hide resolved
Co-authored-by: Jan Jones <jan.jones.cz@gmail.com>
Add extra tests
Add init test
| } | ||
|
|
||
| // containing type implements IComponent | ||
| if (!symbol.ContainingType.AllInterfaces.Any(@interface => @interface.Equals(componentSymbol, SymbolEqualityComparer.Default))) |
There was a problem hiding this comment.
nit: not sure if we have an overload like this available
| if (!symbol.ContainingType.AllInterfaces.Any(@interface => @interface.Equals(componentSymbol, SymbolEqualityComparer.Default))) | |
| if (!symbol.ContainingType.AllInterfaces.Any(static (@interface, componentSymbol) => @interface.Equals(componentSymbol, SymbolEqualityComparer.Default), componentSymbol)) |
...oft.CodeAnalysis.Razor.Compiler/src/Analyzers/ComponentParameterNullableWarningSuppressor.cs
Outdated
Show resolved
Hide resolved
…rs/ComponentParameterNullableWarningSuppressor.cs Co-authored-by: Fred Silberberg <fred@silberberg.xyz>
|
@chsienki If the component has a constructor, CS8618 puts the warning on the constructor rather than on the property. It seems this suppressor does not work as it should when components have a constructor defined. Also, I would still love to see this suppressor for |

Adds a suppressor for CS8618 when a component property has
EditorRequiredattached to it.