Fix OptionsValidator source-gen to skip static and const members (#88254)
authorNikita Balabaev <xakep139@users.noreply.github.com>
Sun, 2 Jul 2023 18:37:07 +0000 (20:37 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Jul 2023 18:37:07 +0000 (11:37 -0700)
Co-authored-by: Nikita Balabaev <nbalabaev@microsoft.com>
21 files changed:
docs/project/list-of-diagnostics.md
src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.sln
src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs
src/libraries/Microsoft.Extensions.Options/gen/Parser.cs
src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf
src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf
src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs
src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx
src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx

index d63a0b8..e5ea1f5 100644 (file)
@@ -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.* |
index 87a7d0a..3935bd8 100644 (file)
@@ -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}"
@@ -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}"
@@ -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
@@ -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}
index e76363f..10ab32c 100644 (file)
@@ -91,5 +91,12 @@ namespace Microsoft.Extensions.Options.Generators
             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);
     }
 }
index 2a9215c..dad40ee 100644 (file)
@@ -448,6 +448,20 @@ namespace Microsoft.Extensions.Options.Generators
                 }
             }
 
+            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)
             {
@@ -462,7 +476,7 @@ namespace Microsoft.Extensions.Options.Generators
             }
 
             // 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)
@@ -478,7 +492,7 @@ namespace Microsoft.Extensions.Options.Generators
                 }
             }
 
-            if (validationAttrs.Count > 0 || transValidatorTypeName is not null || enumerationValidatorTypeName is not null)
+            if (validationAttributeIsApplied)
             {
                 return new(
                     member.Name,
index 021f345..76c83d1 100644 (file)
   <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>
index e2488a7..7d241c4 100644 (file)
         <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>
index df204ef..926cc18 100644 (file)
         <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>
index 184bbb3..26ceb1b 100644 (file)
         <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>
index cb0596b..47973e8 100644 (file)
         <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>
index 2bbb76d..3ca838d 100644 (file)
         <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>
index 00a2e4f..64929dd 100644 (file)
         <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>
index 14137b6..98d9d90 100644 (file)
         <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>
index 5766d2a..ce7e2e2 100644 (file)
         <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>
index b226f9c..522506b 100644 (file)
         <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>
index 3bb2c0e..61ac1d7 100644 (file)
         <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="needs-review-translation">Не удается применить атрибуты проверки к константе, статическому полю или свойству {0}.</target>
+        <note />
+      </trans-unit>
+      <trans-unit id="CantValidateStaticOrConstMemberTitle">
+        <source>Can't validate constants, static fields or properties.</source>
+        <target state="needs-review-translation">Не удается проверить статические поля или свойства, в т.ч. константы.</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>
@@ -59,7 +69,7 @@
       </trans-unit>
       <trans-unit id="MemberIsInaccessibleTitle">
         <source>Can't validate private fields or properties.</source>
-        <target state="translated">Не удается проверить частные поля или свойства.</target>
+        <target state="translated">Не удается проверить приватные поля или свойства.</target>
         <note />
       </trans-unit>
       <trans-unit id="NoEligibleMemberMessage">
index 6d56473..a0d0ab6 100644 (file)
         <target state="translated">Açık genel türleri olan alanlarda veya özelliklerde 'ValidateObjectMembersAttribute' veya 'ValidateEnumeratedItemsAttribute' kullanılamaz.</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">Statik doğrulama için kullanılmasını engelleyen {0} türü içeren döngüsel bir tür başvurusu var.</target>
index edd5917..f21739b 100644 (file)
         <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>
index ee2d977..9d05a46 100644 (file)
         <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>
index ad094f9..08805c7 100644 (file)
@@ -164,6 +164,80 @@ namespace __OptionValidationStaticInstances
     }
 
     [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+    public async Task IgnoredStaticMembers()
+    {
+        var (d, _) = await RunGenerator(@"
+            public class FirstModel
+            {
+                // Since we ignore static members, we shouldn't check SecondModel,
+                // and shouldn't emit the 'SYSLIB1212' warning about potentially missing transitive validation
+                public static SecondModel? P1 { get; set; }
+
+                public static SecondModel P2 = new();
+
+                public static System.Collections.Generic.IList<SecondModel>? P3 { get; set; }
+
+                public const SecondModel P4 = null;
+
+                [Required]
+                public string Name { get; set; } = nameof(FirstModel);
+            }
+
+            public class SecondModel
+            {
+                [Required]
+                public string? P3;
+            }
+
+            [OptionsValidator]
+            public partial class FirstModelValidator : IValidateOptions<FirstModel>
+            {
+            }
+        ");
+
+        Assert.Empty(d);
+    }
+
+    [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+    public async Task ValidationAttributeOnStaticMember()
+    {
+        var (d, _) = await RunGenerator(@"
+            public class FirstModel
+            {
+                [Required]
+                public static string? P1 { get; set; }
+
+                [Required]
+                public const string? P1;
+
+                [ValidateObjectMembers]
+                public static SecondModel P2 = new();
+
+                [ValidateEnumeratedItems]
+                public static System.Collections.Generic.IList<SecondModel>? P3 { get; set; }
+
+                [Required]
+                public string Name { get; set; } = nameof(FirstModel);
+            }
+
+            public class SecondModel
+            {
+                [Required]
+                public string? P3;
+            }
+
+            [OptionsValidator]
+            public partial class FirstModelValidator : IValidateOptions<FirstModel>
+            {
+            }
+        ");
+
+        Assert.Equal(4, d.Count);
+        Assert.All(d, x => Assert.Equal(DiagDescriptors.CantValidateStaticOrConstMember.Id, x.Id));
+        Assert.All(d, x => Assert.Equal(DiagnosticSeverity.Warning, x.DefaultSeverity));
+    }
+
+    [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
     public async Task CircularTypeReferences()
     {
         var (diagnostics, _) = await RunGenerator(@"
index 1673d46..b3a449b 100644 (file)
   <data name="PotentiallyMissingTransitiveValidationTitle" xml:space="preserve">
     <value>Member potentially missing transitive validation.</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>
 </root>
\ No newline at end of file
index 1673d46..b3a449b 100644 (file)
   <data name="PotentiallyMissingTransitiveValidationTitle" xml:space="preserve">
     <value>Member potentially missing transitive validation.</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>
 </root>
\ No newline at end of file