diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 5bdbbd518caac0ed5c15fa3247b84278ed004337..2375aa96652c85f6ab967d04b32cdb62490acfb5 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -249,11 +249,11 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIB1212`__ | Options validation generator: Member potentially missing transitive validation. | | __`SYSLIB1213`__ | Options validation generator: Member potentially missing enumerable validation. | | __`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.* | -| __`SYSLIB1218`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | -| __`SYSLIB1219`__ | *_`SYSLIB1214`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1215`__ | Options validation generator: Validation attribute on the member is inaccessible from the validator type. | +| __`SYSLIB1216`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1217`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1218`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1219`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | | __`SYSLIB1220`__ | JsonSourceGenerator encountered a [JsonConverterAttribute] with an invalid type argument. | | __`SYSLIB1221`__ | JsonSourceGenerator does not support this C# language version. | | __`SYSLIB1222`__ | Constructor annotated with JsonConstructorAttribute is inaccessible. | diff --git a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs index 10ab32c19c0bd46cbee2e010a248185721fb7746..474686189fb126cd792940ee1bdd96fb17c10cd0 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs @@ -98,5 +98,12 @@ internal sealed class DiagDescriptors : DiagDescriptorsBase messageFormat: SR.CantValidateStaticOrConstMemberMessage, category: Category, defaultSeverity: DiagnosticSeverity.Warning); + + public static DiagnosticDescriptor InaccessibleValidationAttribute { get; } = Make( + id: "SYSLIB1215", + title: SR.InaccessibleValidationAttributeTitle, + messageFormat: SR.InaccessibleValidationAttributeMessage, + category: Category, + defaultSeverity: DiagnosticSeverity.Info); } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index d71138daa917362891ed2c882cf633fa3447baab..0876ffa53e6a372407d77d9c4f8b3d8d17599106 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -97,7 +97,7 @@ public IReadOnlyList GetValidatorTypes(IEnumerable<(TypeDeclarati ? modelType.GetLocation() : syntax.GetLocation(); - var membersToValidate = GetMembersToValidate(modelType, true, lowerLocationInCompilation); + var membersToValidate = GetMembersToValidate(modelType, true, lowerLocationInCompilation, validatorType); if (membersToValidate.Count == 0) { // this type lacks any eligible members @@ -243,7 +243,7 @@ private static bool HasOpenGenerics(ITypeSymbol type, out string genericType) return null; } - private List GetMembersToValidate(ITypeSymbol modelType, bool speculate, Location lowerLocationInCompilation) + private List GetMembersToValidate(ITypeSymbol modelType, bool speculate, Location lowerLocationInCompilation, ITypeSymbol validatorType) { // make a list of the most derived members in the model type @@ -271,7 +271,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s ? member.GetLocation() : lowerLocationInCompilation; - var memberInfo = GetMemberInfo(member, speculate, location); + var memberInfo = GetMemberInfo(member, speculate, location, validatorType); if (memberInfo is not null) { if (member.DeclaredAccessibility != Accessibility.Public && member.DeclaredAccessibility != Accessibility.Internal) @@ -287,7 +287,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s return membersToValidate; } - private ValidatedMember? GetMemberInfo(ISymbol member, bool speculate, Location location) + private ValidatedMember? GetMemberInfo(ISymbol member, bool speculate, Location location, ITypeSymbol validatorType) { ITypeSymbol memberType; switch (member) @@ -370,7 +370,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s if (transValidatorTypeName == null) { transValidatorIsSynthetic = true; - transValidatorTypeName = AddSynthesizedValidator(memberType, member, location); + transValidatorTypeName = AddSynthesizedValidator(memberType, member, location, validatorType); } // pop the stack @@ -433,7 +433,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s if (enumerationValidatorTypeName == null) { enumerationValidatorIsSynthetic = true; - enumerationValidatorTypeName = AddSynthesizedValidator(enumeratedType, member, location); + enumerationValidatorTypeName = AddSynthesizedValidator(enumeratedType, member, location, validatorType); } // pop the stack @@ -441,6 +441,12 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s } else if (ConvertTo(attributeType, _symbolHolder.ValidationAttributeSymbol)) { + if (!_compilation.IsSymbolAccessibleWithin(attributeType, validatorType)) + { + Diag(DiagDescriptors.InaccessibleValidationAttribute, location, attributeType.Name, member.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), validatorType.Name); + continue; + } + var validationAttr = new ValidationAttributeInfo(attributeType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); validationAttrs.Add(validationAttr); @@ -475,7 +481,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s { if (!HasOpenGenerics(memberType, out var genericType)) { - var membersToValidate = GetMembersToValidate(memberType, false, location); + var membersToValidate = GetMembersToValidate(memberType, false, location, validatorType); if (membersToValidate.Count > 0) { Diag(DiagDescriptors.PotentiallyMissingTransitiveValidation, location, memberType.Name, member.Name); @@ -491,7 +497,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s { if (!HasOpenGenerics(enumeratedType, out var genericType)) { - var membersToValidate = GetMembersToValidate(enumeratedType, false, location); + var membersToValidate = GetMembersToValidate(enumeratedType, false, location, validatorType); if (membersToValidate.Count > 0) { Diag(DiagDescriptors.PotentiallyMissingEnumerableValidation, location, enumeratedType.Name, member.Name); @@ -519,7 +525,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s return null; } - private string? AddSynthesizedValidator(ITypeSymbol modelType, ISymbol member, Location location) + private string? AddSynthesizedValidator(ITypeSymbol modelType, ISymbol member, Location location, ITypeSymbol validatorType) { var mt = modelType.WithNullableAnnotation(NullableAnnotation.None); if (mt.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) @@ -533,7 +539,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s return "global::" + validator.Namespace + "." + validator.Name; } - var membersToValidate = GetMembersToValidate(mt, true, location); + var membersToValidate = GetMembersToValidate(mt, true, location, validatorType); if (membersToValidate.Count == 0) { // this type lacks any eligible members diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx index 76c83d10f7ef4ac4364d11b556a6a26413e2c11f..ef074f147f915ebcbf35fcaeda8e1524f4af23c9 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx @@ -201,4 +201,10 @@ Validators used for transitive or enumerable validation must have a constructor with no parameters. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + Validation attribute on the member is inaccessible from the validator type.. + diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index 60d2178fcef772c21504b799c05f7bcc564dc2b6..93d5d146b6ea4682db44a8885898a1f1ea632925 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -62,6 +62,16 @@ Typ anotovaný třídou OptionsValidatorAttribute neimplementuje nezbytné rozhraní. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Ověřovací atributy nelze použít u privátního pole nebo vlastnosti {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index bb2cd51adbc71ddc31d8355cb7f20de883824cbd..f8d47cfea1d2664e75c682ae3431e0da8b08cb1d 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -62,6 +62,16 @@ Ein mit "OptionsValidatorAttribute" versehener Typ implementiert nicht die erforderliche Schnittstelle. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Validierungsattribute können nicht auf private Felder oder Eigenschaften {0} angewendet werden. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 072faa4a301e7ed89a55e86bad0625816b158165..5a510041df2c231db0d2f33a8d4b15d83480b8c6 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -62,6 +62,16 @@ Un tipo anotado con “OptionsValidatorAttribute” no implementa la interfaz necesaria. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. No se pueden aplicar atributos de validación a la propiedad o campo privado {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index ac0b2746e3df9040f4f71acb4d3d2247feaf0302..0f18794aed0a3b7e00da00730f321c595a890464 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -62,6 +62,16 @@ Un type annoté avec 'OptionsValidatorAttribute' n’implémente pas l’interface nécessaire. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Impossible d’appliquer les attributs de validation au champ privé ou à la propriété {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index 9d9b7ec036c16ea98b2e8c71131a71c7a8dfcda7..666874e8f404a9c61616d4683841bc9bab7c0d81 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -62,6 +62,16 @@ Un tipo annotato con 'OptionsValidatorAttribute' non implementa l'interfaccia necessaria. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Non è possibile applicare gli attributi di convalida al campo privato o alla proprietà {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index 49cd4a517745dc6b4becbf3a33c5848ce6fa0870..a8c4f10a47dbb98e6f08c33e926cec48438cf0ba 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -62,6 +62,16 @@ 'OptionsValidatorAttribute' の注釈が付けられた型が、必要とされるインターフェイスを実装していません。 + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. プライベート フィールドまたはプロパティ {0} には検証属性を適用できません。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index 2593e7ddab6a02991d65160c1069238fb4b88a9c..6ccb8a4ab759e415e9614b56bd09282a55b5bcf6 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -62,6 +62,16 @@ 'OptionsValidatorAttribute'로 주석이 추가된 형식은 필요한 인터페이스를 구현하지 않습니다. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. 프라이빗 필드 또는 속성 {0}에 유효성 검사 특성을 적용할 수 없습니다. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index e3fe9a64adf8159bd9acfba47c9c53040826cfdf..116778abc1a01188f7dd7d8854ef823386951fbc 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -62,6 +62,16 @@ Typ z adnotacją „OptionsValidatorAttribute” nie implementuje wymaganego interfejsu. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Nie można zastosować atrybutów weryfikacji do pola prywatnego lub właściwości {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index a3ece4244c52543e13fe1e23d21b8d5ad8266659..b575119e0fecc2497202bfa4324ccf8fb3d8a81c 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -62,6 +62,16 @@ Um tipo anotado com "OptionsValidatorAttribute" não implementa a interface necessária. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Não é possível aplicar atributos de validação a um campo privado ou propriedade {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index 72d7311a5bf5b67719ef0716d5d079b9819de858..0ffb4ad98e29fec80475e14e120cadc62fb9f972 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -62,6 +62,16 @@ Тип с аннотацией OptionsValidatorAttribute не реализует необходимый интерфейс. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Не удается применить атрибуты проверки к закрытому полю или свойству {0}. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index 728f28b6c98e4870739bb6136fbeb0e0e4b73644..a2859559cbb1b44218fe248b743e4c32ad850f81 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -62,6 +62,16 @@ 'OptionsValidatorAttribute' ile açıklama eklenmiş bir tür gerekli arabirimi uygulamıyor. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. Doğrulama öznitelikleri, {0} özel alanına veya özelliğine uygulanamıyor. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index 92dafa1bb7290821b2bc37ec2cf8496eb5492a3f..73347ccc6e5b3de641af264d93d8668005269057 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -62,6 +62,16 @@ 用 "OptionsValidatorAttribute" 批注的类型未实现必要的接口。 + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. 无法将验证属性应用于专用字段或属性 {0}。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index a82e4e2fabfb0c6ef67e1a7c51695c604c63f96d..0bc6a55328d8faf725631466305fde8ebf217ca1 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -62,6 +62,16 @@ 以 'OptionsValidatorAttribute' 附註的類型未實作必要的介面。 + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + + Validation attribute on the member is inaccessible from the validator type.. + Validation attribute on the member is inaccessible from the validator type.. + + Can't apply validation attributes to private field or property {0}. 無法將驗證屬性套用至私用欄位或屬性 {0}。 diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index 17ea4bca02cb07c9c33ac919151ef4a7930e6339..741dff2c38e9d96c10913bd5c238cadf07cc04e1 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -1179,7 +1179,9 @@ public SecondValidator(int _) Assert.Equal(DiagDescriptors.ValidatorsNeedSimpleConstructor.Id, diagnostics[0].Id); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + private static bool SupportRemoteExecutionAndNotInBrowser => RemoteExecutor.IsSupported && !PlatformDetection.IsBrowser; + + [ConditionalFact(nameof(SupportRemoteExecutionAndNotInBrowser))] public void ProduceDiagnosticFromOtherAssemblyTest() { string source = """ @@ -1264,6 +1266,176 @@ public class MyOptions File.Delete(assemblyPath); // cleanup } + [ConditionalFact(nameof(SupportRemoteExecutionAndNotInBrowser))] + public async Task InaccessibleValidationAttributesTest() + { + string source = """ + using System; + using System.ComponentModel.DataAnnotations; + + #nullable enable + + namespace ValidationTest; + + public class BaseOptions + { + [Timeout] // internal attribute not visible outside the assembly + public int Prop1 { get; set; } + + [Required] + public string Prop2 { get; set; } + } + + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class TimeoutAttribute : ValidationAttribute + { + protected override ValidationResult IsValid(object? value, ValidationContext? validationContext) + { + return ValidationResult.Success!; + } + } + """; + + string assemblyName = Path.GetRandomFileName(); + string assemblyPath = Path.Combine(Path.GetTempPath(), assemblyName + ".dll"); + + var compilation = CSharpCompilation + .Create(assemblyName, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) + .AddReferences(MetadataReference.CreateFromFile(AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == "System.Runtime").Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(RequiredAttribute).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(OptionsValidatorAttribute).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(IValidateOptions).Assembly.Location)) + .AddSyntaxTrees(CSharpSyntaxTree.ParseText(source)); + + EmitResult emitResult = compilation.Emit(assemblyPath); + Assert.True(emitResult.Success); + + RemoteExecutor.Invoke(async (assemblyFullPath) => { + string source0 = """ + using Microsoft.Extensions.Options; + """; + + string source1 = """ + using System.ComponentModel.DataAnnotations; + + #nullable enable + #pragma warning disable CS1591 + + namespace ValidationTest + { + public class ExtOptions : BaseOptions + { + [Range(0, 10)] + public int Prop3 { get; set; } + } + } + """; + + string source2 = """ + namespace ValidationTest + { + [OptionsValidator] + internal sealed partial class ExtOptionsValidator : IValidateOptions + { + } + } + """; + + Assembly assembly = Assembly.LoadFrom(assemblyFullPath); + + var (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new Generator(), + new[] + { + assembly, + Assembly.GetAssembly(typeof(RequiredAttribute)), + Assembly.GetAssembly(typeof(OptionsValidatorAttribute)), + Assembly.GetAssembly(typeof(IValidateOptions)), + }, + new List { source0 + source1 + source2 }) + .ConfigureAwait(false); + + _ = Assert.Single(generatedSources); + Assert.Single(diagnostics); + Assert.Equal(DiagDescriptors.InaccessibleValidationAttribute.Id, diagnostics[0].Id); + string generatedSource = generatedSources[0].SourceText.ToString(); + Assert.Contains("global::System.ComponentModel.DataAnnotations.RangeAttribute", generatedSource); + Assert.Contains("global::System.ComponentModel.DataAnnotations.RequiredAttribute", generatedSource); + Assert.DoesNotContain("Timeout", generatedSource); + + // Ensure the generated source compiles + var compilation = CSharpCompilation + .Create(Path.GetRandomFileName()+".dll", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) + .AddReferences(MetadataReference.CreateFromFile(AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == "System.Runtime").Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(RequiredAttribute).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(OptionsValidatorAttribute).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(IValidateOptions).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).Assembly.Location)) + .AddReferences(MetadataReference.CreateFromFile(assemblyFullPath)) + .AddSyntaxTrees(CSharpSyntaxTree.ParseText(source1 + Environment.NewLine + generatedSource)); + + MemoryStream ms = new(); + EmitResult emitResult = compilation.Emit(ms); + Assert.True(emitResult.Success); + }, assemblyPath).Dispose(); + + File.Delete(assemblyPath); // cleanup + + // Test private validation attribute in the same assembly + + string source3 = """ + using System; + using System.ComponentModel.DataAnnotations; + using Microsoft.Extensions.Options; + + #nullable enable + + namespace ValidationTest; + + public class MyOptions + { + [Timeout] // private attribute + public int Prop1 { get; set; } + + [Required] + public string Prop2 { get; set; } + + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] + private sealed class TimeoutAttribute : ValidationAttribute + { + protected override ValidationResult IsValid(object? value, ValidationContext? validationContext) + { + return ValidationResult.Success!; + } + } + } + + [OptionsValidator] + public sealed partial class MyOptionsValidator : IValidateOptions + { + } + """; + + var (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new Generator(), + new[] + { + Assembly.GetAssembly(typeof(RequiredAttribute)), + Assembly.GetAssembly(typeof(OptionsValidatorAttribute)), + Assembly.GetAssembly(typeof(IValidateOptions)), + }, + new List { source3 }) + .ConfigureAwait(false); + + _ = Assert.Single(generatedSources); + Assert.Single(diagnostics); + Assert.Equal(DiagDescriptors.InaccessibleValidationAttribute.Id, diagnostics[0].Id); + string generatedSource = generatedSources[0].SourceText.ToString(); + Assert.DoesNotContain("Timeout", generatedSource); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public async Task CantValidateOpenGenericMembersInEnumeration() { diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx index b3a449b3c9812b750aec46cdeb1880e4a464b547..c6d9021ea9967223c341d401ecd80d347ffe9499 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx @@ -204,4 +204,10 @@ Can't validate constants, static fields or properties. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + Validation attribute on the member is inaccessible from the validator type.. + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx index b3a449b3c9812b750aec46cdeb1880e4a464b547..c6d9021ea9967223c341d401ecd80d347ffe9499 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx @@ -204,4 +204,10 @@ Can't validate constants, static fields or properties. + + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + + + Validation attribute on the member is inaccessible from the validator type.. + \ No newline at end of file