Skip to content

Commit

Permalink
Fix OptionsValidator source-gen to skip static and const members (#88254
Browse files Browse the repository at this point in the history
)

Co-authored-by: Nikita Balabaev <[email protected]>
  • Loading branch information
xakep139 and xakep139 authored Jul 2, 2023
1 parent 0d77cf0 commit 779d536
Show file tree
Hide file tree
Showing 21 changed files with 275 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/project/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
| __`SYSLIB1211`__ | Options validation generator: Unsupported circular references in model types. |
| __`SYSLIB1212`__ | Options validation generator: Member potentially missing transitive validation. |
| __`SYSLIB1213`__ | Options validation generator: Member potentially missing enumerable validation. |
| __`SYSLIB1214`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* |
| __`SYSLIB1214`__ | Options validation generator: Can't validate constants, static fields or properties. |
| __`SYSLIB1215`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* |
| __`SYSLIB1216`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* |
| __`SYSLIB1217`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Option
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "src\Microsoft.Extensions.Options.csproj", "{9BA945E7-0970-4CA2-A54B-F8D9B3E69917}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.SourceGeneration", "gen\Microsoft.Extensions.Options.SourceGeneration.csproj", "{2B8ED012-22B5-47DD-A879-FD2AFD4C067D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.Tests", "tests\Microsoft.Extensions.Options.Tests\Microsoft.Extensions.Options.Tests.csproj", "{94CAA850-ABDB-4A1E-B18B-19DA0DE75CFD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.SourceGeneration.Unit.Tests", "tests\SourceGeneration.Unit.Tests\Microsoft.Extensions.Options.SourceGeneration.Unit.Tests.csproj", "{D3B6805B-F10E-4A19-99FC-55506892BC18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.SourceGeneration.Tests", "tests\SourceGenerationTests\Microsoft.Extensions.Options.SourceGeneration.Tests.csproj", "{D7C2C4C7-CF28-4E2B-8749-31D7E6072588}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\ref\Microsoft.Extensions.Primitives.csproj", "{36C471D8-1D7A-4C81-8B05-2EED0984FBB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\src\Microsoft.Extensions.Primitives.csproj", "{AAB5D437-EFB2-4BAC-BA0F-7323BA691B89}"
Expand All @@ -123,6 +129,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Concurre
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections", "..\System.Collections\ref\System.Collections.csproj", "{6AE427EF-C018-4075-A4C8-BF3831C5F88C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ComponentModel.Annotations", "..\System.ComponentModel.Annotations\src\System.ComponentModel.Annotations.csproj", "{90548F7B-C673-42C9-BD88-A6E6550ECE1C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.DiagnosticSource", "..\System.Diagnostics.DiagnosticSource\ref\System.Diagnostics.DiagnosticSource.csproj", "{6A1A3AFF-C018-498A-80A0-532396132AD5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.DiagnosticSource", "..\System.Diagnostics.DiagnosticSource\src\System.Diagnostics.DiagnosticSource.csproj", "{429C9D71-4BBD-489D-9C86-EC240F652008}"
Expand Down Expand Up @@ -487,6 +495,22 @@ Global
{D7CEC738-5D2D-4FCB-9268-9650EB01BF31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7CEC738-5D2D-4FCB-9268-9650EB01BF31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7CEC738-5D2D-4FCB-9268-9650EB01BF31}.Release|Any CPU.Build.0 = Release|Any CPU
{2B8ED012-22B5-47DD-A879-FD2AFD4C067D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B8ED012-22B5-47DD-A879-FD2AFD4C067D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B8ED012-22B5-47DD-A879-FD2AFD4C067D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B8ED012-22B5-47DD-A879-FD2AFD4C067D}.Release|Any CPU.Build.0 = Release|Any CPU
{D3B6805B-F10E-4A19-99FC-55506892BC18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3B6805B-F10E-4A19-99FC-55506892BC18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3B6805B-F10E-4A19-99FC-55506892BC18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3B6805B-F10E-4A19-99FC-55506892BC18}.Release|Any CPU.Build.0 = Release|Any CPU
{D7C2C4C7-CF28-4E2B-8749-31D7E6072588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7C2C4C7-CF28-4E2B-8749-31D7E6072588}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7C2C4C7-CF28-4E2B-8749-31D7E6072588}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7C2C4C7-CF28-4E2B-8749-31D7E6072588}.Release|Any CPU.Build.0 = Release|Any CPU
{90548F7B-C673-42C9-BD88-A6E6550ECE1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90548F7B-C673-42C9-BD88-A6E6550ECE1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90548F7B-C673-42C9-BD88-A6E6550ECE1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90548F7B-C673-42C9-BD88-A6E6550ECE1C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -571,6 +595,10 @@ Global
{B5F25A78-B7FB-460B-9B71-BE82D22923FD} = {C25891DB-FBAC-4B92-9BB9-A8181B5A0EF1}
{E06CE29E-15EB-4C0E-97B7-4367FFEDD98D} = {C25891DB-FBAC-4B92-9BB9-A8181B5A0EF1}
{9021FD06-E11E-42DE-87EF-A1040BA5DB56} = {C25891DB-FBAC-4B92-9BB9-A8181B5A0EF1}
{2B8ED012-22B5-47DD-A879-FD2AFD4C067D} = {C25891DB-FBAC-4B92-9BB9-A8181B5A0EF1}
{D3B6805B-F10E-4A19-99FC-55506892BC18} = {7C1317AA-5F4C-42A4-80F3-856BA5E204AF}
{D7C2C4C7-CF28-4E2B-8749-31D7E6072588} = {7C1317AA-5F4C-42A4-80F3-856BA5E204AF}
{90548F7B-C673-42C9-BD88-A6E6550ECE1C} = {7028EE0A-D314-4F48-91CA-51A1633BC3F4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FE89CDC6-6313-439C-85D7-A81D5DF593E9}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,12 @@ internal sealed class DiagDescriptors : DiagDescriptorsBase
messageFormat: SR.PotentiallyMissingEnumerableValidationMessage,
category: Category,
defaultSeverity: DiagnosticSeverity.Warning);

public static DiagnosticDescriptor CantValidateStaticOrConstMember { get; } = Make(
id: "SYSLIB1214",
title: SR.CantValidateStaticOrConstMemberTitle,
messageFormat: SR.CantValidateStaticOrConstMemberMessage,
category: Category,
defaultSeverity: DiagnosticSeverity.Warning);
}
}
18 changes: 16 additions & 2 deletions src/libraries/Microsoft.Extensions.Options/gen/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,20 @@ private List<ValidatedMember> GetMembersToValidate(ITypeSymbol modelType, bool s
}
}

bool validationAttributeIsApplied = validationAttrs.Count > 0 || transValidatorTypeName is not null || enumerationValidatorTypeName is not null;

if (member.IsStatic)
{
// generate a warning if the member is const/static and has a validation attribute applied
if (validationAttributeIsApplied)
{
Diag(DiagDescriptors.CantValidateStaticOrConstMember, member.GetLocation(), member.Name);
}

// don't validate the member in any case
return null;
}

// generate a warning if the field/property seems like it should be transitively validated
if (transValidatorTypeName == null && speculate && memberType.SpecialType == SpecialType.None)
{
Expand All @@ -462,7 +476,7 @@ private List<ValidatedMember> GetMembersToValidate(ITypeSymbol modelType, bool s
}

// generate a warning if the field/property seems like it should be enumerated
if (enumerationValidatorTypeName == null && speculate)
if (enumerationValidatorTypeName == null && speculate && memberType.SpecialType != SpecialType.System_String)
{
var enumeratedType = GetEnumeratedType(memberType);
if (enumeratedType is not null)
Expand All @@ -478,7 +492,7 @@ private List<ValidatedMember> GetMembersToValidate(ITypeSymbol modelType, bool s
}
}

if (validationAttrs.Count > 0 || transValidatorTypeName is not null || enumerationValidatorTypeName is not null)
if (validationAttributeIsApplied)
{
return new(
member.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@
<data name="CantUseWithGenericTypesTitle" xml:space="preserve">
<value>Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types.</value>
</data>
<data name="CantValidateStaticOrConstMemberMessage" xml:space="preserve">
<value>Can't apply validation attributes to constant or static member {0}.</value>
</data>
<data name="CantValidateStaticOrConstMemberTitle" xml:space="preserve">
<value>Can't validate constants, static fields or properties.</value>
</data>
<data name="CircularTypeReferencesMessage" xml:space="preserve">
<value>There is a circular type reference involving type {0} preventing it from being used for static validation.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">U polí nebo vlastností s otevřenými obecnými typy nelze použít ValidateObjectMembersAttribute nebo ValidateEnumeratedItemsAttribute.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Existuje cyklický odkaz obsahující typ {0}, který brání jeho použití pro statické ověření.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">"ValidateObjectMembersAttribute" oder "ValidateEnumeratedItemsAttribute" kann nicht für Felder oder Eigenschaften mit offenen generischen Typen verwendet werden.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Es gibt einen Zirkelverweis, der den Typ "{0}" verhindert, dass er für die statische Validierung verwendet wird.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">No se puede usar “ValidateObjectMembersAttribute” o “ValidateEnumeratedItemsAttribute” en campos o propiedades con tipos genéricos abiertos.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Hay una referencia de tipo circular que implica al tipo {0} que impide que se use para la validación estática.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">Impossible d’utiliser 'ValidateObjectMembersAttribute' ou 'ValidateEnumeratedItemsAttribute' sur des champs ou des propriétés avec des types génériques ouverts.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Une référence de type circulaire implique un type {0} l’empêche d’être utilisé pour la validation statique.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">Non è possibile usare 'ValidateObjectMembersAttribute' o 'ValidateEnumeratedItemsAttribute' nei campi o nelle proprietà con tipi generici aperti.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Esiste un riferimento di tipo circolare che interessa il tipo {0} e ne impedisce l'utilizzo per la convalida statica.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">'ValidateObjectMembersAttribute' または 'ValidateEnumeratedItemsAttribute' は、オープンジェネリック型を持つフィールドまたはプロパティでは使用できません。</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">型{0}を含む循環型参照があるため、静的検証に使用できません。</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">열린 제네릭 형식의 필드 또는 속성에는 'ValidateObjectMembersAttribute' 또는 'ValidateEnumeratedItemsAttribute'를 사용할 수 없습니다.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">정적 유효성 검사에 사용할 수 없으므로 형식 {0} 관련된 순환 형식 참조가 있습니다.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">Nie można użyć atrybutu „ValidateObjectMembersAttribute” lub „ValidateEnumeratedItemsAttribute” w polach lub właściwościach z otwartymi typami ogólnymi.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Istnieje cykliczne odwołanie do typu dotyczące typu {0} uniemożliwiające użycie go do weryfikacji statycznej.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<target state="translated">Não é possível usar "ValidateObjectMembersAttribute" ou "ValidateEnumeratedItemsAttribute" em campos ou propriedades com tipos genéricos abertos.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberMessage">
<source>Can't apply validation attributes to constant or static member {0}.</source>
<target state="new">Can't apply validation attributes to constant or static member {0}.</target>
<note />
</trans-unit>
<trans-unit id="CantValidateStaticOrConstMemberTitle">
<source>Can't validate constants, static fields or properties.</source>
<target state="new">Can't validate constants, static fields or properties.</target>
<note />
</trans-unit>
<trans-unit id="CircularTypeReferencesMessage">
<source>There is a circular type reference involving type {0} preventing it from being used for static validation.</source>
<target state="translated">Há uma referência de tipo circular que envolve o tipo {0} que a impede de ser usada para validação estática.</target>
Expand Down
Loading

0 comments on commit 779d536

Please sign in to comment.