Make component parameter analyzer allow public getters. Imported from Blazor PR 1702. (#4594)

This commit is contained in:
Steve Sanderson 2018-12-14 18:50:45 +00:00 committed by GitHub
parent d30c407dd0
commit ec9676f51e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 12 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Components.Shared; using Microsoft.AspNetCore.Components.Shared;
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers
.Where(attr => semanticModel.GetTypeInfo(attr).Type?.ToDisplayString() == ComponentsApi.ParameterAttribute.FullTypeName) .Where(attr => semanticModel.GetTypeInfo(attr).Type?.ToDisplayString() == ComponentsApi.ParameterAttribute.FullTypeName)
.FirstOrDefault(); .FirstOrDefault();
if (parameterAttribute != null && IsPublic(declaration)) if (parameterAttribute != null && IsPubliclySettable(declaration))
{ {
var identifierText = declaration.Identifier.Text; var identifierText = declaration.Identifier.Text;
if (!string.IsNullOrEmpty(identifierText)) if (!string.IsNullOrEmpty(identifierText))
@ -60,7 +60,17 @@ namespace Microsoft.AspNetCore.Components.Analyzers
} }
} }
private static bool IsPublic(PropertyDeclarationSyntax declaration) private static bool IsPubliclySettable(PropertyDeclarationSyntax declaration)
=> declaration.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword)); {
// If the property has a setter explicitly marked private/protected/internal, then it's not public
var setter = declaration.AccessorList?.Accessors.SingleOrDefault(x => x.Keyword.IsKind(SyntaxKind.SetKeyword));
if (setter != null && setter.Modifiers.Any(x => x.IsKind(SyntaxKind.PrivateKeyword) || x.IsKind(SyntaxKind.ProtectedKeyword) || x.IsKind(SyntaxKind.InternalKeyword)))
{
return false;
}
// Otherwise fallback to the property declaration modifiers
return declaration.Modifiers.Any(x => x.IsKind(SyntaxKind.PublicKeyword));
}
} }
} }

View File

@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Component parameters should not be public.. /// Looks up a localized string similar to Component parameters should not have public setters..
/// </summary> /// </summary>
internal static string ComponentParametersShouldNotBePublic_Description { internal static string ComponentParametersShouldNotBePublic_Description {
get { get {
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Component parameter &apos;{0}&apos; is marked public, but component parameters should not be public.. /// Looks up a localized string similar to Component parameter &apos;{0}&apos; has a public setter, but component parameters should not be publicly settable..
/// </summary> /// </summary>
internal static string ComponentParametersShouldNotBePublic_Format { internal static string ComponentParametersShouldNotBePublic_Format {
get { get {
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Component parameter is marked public. /// Looks up a localized string similar to Component parameter has public setter.
/// </summary> /// </summary>
internal static string ComponentParametersShouldNotBePublic_Title { internal static string ComponentParametersShouldNotBePublic_Title {
get { get {

View File

@ -118,15 +118,15 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ComponentParametersShouldNotBePublic_Description" xml:space="preserve"> <data name="ComponentParametersShouldNotBePublic_Description" xml:space="preserve">
<value>Component parameters should not be public.</value> <value>Component parameters should not have public setters.</value>
</data> </data>
<data name="ComponentParametersShouldNotBePublic_FixTitle" xml:space="preserve"> <data name="ComponentParametersShouldNotBePublic_FixTitle" xml:space="preserve">
<value>Make component parameter private</value> <value>Make component parameter private</value>
</data> </data>
<data name="ComponentParametersShouldNotBePublic_Format" xml:space="preserve"> <data name="ComponentParametersShouldNotBePublic_Format" xml:space="preserve">
<value>Component parameter '{0}' is marked public, but component parameters should not be public.</value> <value>Component parameter '{0}' has a public setter, but component parameters should not be publicly settable.</value>
</data> </data>
<data name="ComponentParametersShouldNotBePublic_Title" xml:space="preserve"> <data name="ComponentParametersShouldNotBePublic_Title" xml:space="preserve">
<value>Component parameter is marked public</value> <value>Component parameter has public setter</value>
</data> </data>
</root> </root>

View File

@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers.Test
new DiagnosticResult new DiagnosticResult
{ {
Id = "BL9993", Id = "BL9993",
Message = "Component parameter 'BadProperty1' is marked public, but component parameters should not be public.", Message = "Component parameter 'BadProperty1' has a public setter, but component parameters should not be publicly settable.",
Severity = DiagnosticSeverity.Warning, Severity = DiagnosticSeverity.Warning,
Locations = new[] Locations = new[]
{ {
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers.Test
new DiagnosticResult new DiagnosticResult
{ {
Id = "BL9993", Id = "BL9993",
Message = "Component parameter 'BadProperty2' is marked public, but component parameters should not be public.", Message = "Component parameter 'BadProperty2' has a public setter, but component parameters should not be publicly settable.",
Severity = DiagnosticSeverity.Warning, Severity = DiagnosticSeverity.Warning,
Locations = new[] Locations = new[]
{ {
@ -106,6 +106,25 @@ namespace Microsoft.AspNetCore.Components.Analyzers.Test
}" + BlazorParameterSource); }" + BlazorParameterSource);
} }
[Fact]
public void IgnoresPublicPropertiesWithNonPublicSetterWithParameterAttribute()
{
var test = @"
namespace ConsoleApplication1
{
using " + typeof(ParameterAttribute).Namespace + @";
class TypeName
{
[Parameter] public string MyProperty1 { get; private set; }
[Parameter] public object MyProperty2 { get; protected set; }
[Parameter] public object MyProperty2 { get; internal set; }
}
}" + BlazorParameterSource;
VerifyCSharpDiagnostic(test);
}
protected override CodeFixProvider GetCSharpCodeFixProvider() protected override CodeFixProvider GetCSharpCodeFixProvider()
{ {
return new ComponentParametersShouldNotBePublicCodeFixProvider(); return new ComponentParametersShouldNotBePublicCodeFixProvider();