diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index b613b98efd186..efe21cbb9028b 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6947,4 +6947,16 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
required members
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index e40da273d7c5e..66c91cf9768c0 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2033,5 +2033,9 @@ internal enum ErrorCode
// PROTOTYPE(req): Move above the comment and condense before merge
ERR_RequiredNameDisallowed = 9500,
+ ERR_OverrideMustHaveRequired = 9501,
+ ERR_RequiredMembersCannotBeHidden = 9502,
+ ERR_RequiredMembersCannotBeLessVisibleThanContainingType = 9503,
+ ERR_ExplicitRequiredMembers = 9504,
}
}
diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs
index de2abd9ed0871..8ca68abb3e257 100644
--- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineProperty.cs
@@ -151,6 +151,8 @@ public override bool IsExtern
get { return false; }
}
+ internal override bool IsRequired => false;
+
internal override ObsoleteAttributeData ObsoleteAttributeData
{
get { return null; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs
index 10010ac113676..da38096f344db 100644
--- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs
@@ -150,6 +150,8 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
ImmutableArray.Create(
new TypedConstant(manager.System_Diagnostics_DebuggerBrowsableState, TypedConstantKind.Enum, DebuggerBrowsableState.Never))));
}
+
+ internal override bool IsRequired => false;
}
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs
index d55c65c360a9f..5d5630d1af30d 100644
--- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertySymbol.cs
@@ -129,6 +129,8 @@ public override bool IsAbstract
get { return false; }
}
+ internal override bool IsRequired => false;
+
internal sealed override ObsoleteAttributeData ObsoleteAttributeData
{
get { return null; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs
index 09256e0b3b6f8..536658ed92722 100644
--- a/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/ErrorPropertySymbol.cs
@@ -77,6 +77,8 @@ public ErrorPropertySymbol(Symbol containingSymbol, TypeSymbol type, string name
public override bool IsExtern { get { return false; } }
+ internal override bool IsRequired => false;
+
internal sealed override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } }
public override ImmutableArray Parameters { get { return ImmutableArray.Empty; } }
diff --git a/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs
index 52953a754b53c..3d5fdb7b3d910 100644
--- a/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/FieldSymbol.cs
@@ -325,6 +325,11 @@ internal virtual FieldSymbol AsMember(NamedTypeSymbol newOwner)
return newOwner.IsDefinition ? this : new SubstitutedFieldSymbol(newOwner as SubstitutedNamedTypeSymbol, this);
}
+ ///
+ /// Returns true if this field is required to be set in an object initializer on object creation.
+ ///
+ internal abstract bool IsRequired { get; }
+
#region Use-Site Diagnostics
internal override UseSiteInfo GetUseSiteInfo()
diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs
index 6895447a75757..f5d35611fd6f4 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs
@@ -587,5 +587,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData
{
get { return null; }
}
+
+ // PROTOTYPE(req): Implement
+ internal override bool IsRequired => false;
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs
index 4ea1a910336f1..8e24f9904c191 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs
@@ -462,6 +462,15 @@ public override bool IsStatic
}
}
+ internal override bool IsRequired
+ {
+ get
+ {
+ // PROTOTYPE(req): Implement
+ return false;
+ }
+ }
+
public override ImmutableArray Parameters
{
get { return _parameters; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs
index 72d99b8ffed28..04078ac60e638 100644
--- a/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/PropertySymbol.cs
@@ -182,6 +182,11 @@ public bool IsWriteOnly
}
}
+ ///
+ /// Returns true if this property is required to be set in an object initializer on object creation.
+ ///
+ internal abstract bool IsRequired { get; }
+
///
/// True if the property itself is excluded from code coverage instrumentation.
/// True for source properties marked with .
diff --git a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs
index fee6bf4bcadeb..0c2297b9ce522 100644
--- a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyPropertySymbol.cs
@@ -85,6 +85,8 @@ public SignatureOnlyPropertySymbol(
public override bool IsExtern { get { throw ExceptionUtilities.Unreachable; } }
+ internal override bool IsRequired => throw ExceptionUtilities.Unreachable;
+
internal override ObsoleteAttributeData ObsoleteAttributeData { get { throw ExceptionUtilities.Unreachable; } }
public override AssemblySymbol ContainingAssembly { get { throw ExceptionUtilities.Unreachable; } }
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs
index ceb889a17f5fa..c1bef4222d7c8 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/ModifierUtils.cs
@@ -422,6 +422,14 @@ internal static CSDiagnosticInfo CheckAccessibility(DeclarationModifiers modifie
}
}
+ if ((modifiers & DeclarationModifiers.Required) != 0
+ && symbol.Kind is SymbolKind.Property or SymbolKind.Field
+ && symbol.DeclaredAccessibility < symbol.ContainingType.DeclaredAccessibility)
+ {
+ // Required member '{0}' cannot be less visible than the containing type '{1}'.
+ return new CSDiagnosticInfo(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, symbol, symbol.ContainingType);
+ }
+
return null;
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs
index 08ab93bd28469..27f03f3938c9f 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldSymbol.cs
@@ -154,6 +154,8 @@ internal sealed override bool HasRuntimeSpecialName
return this.Name == WellKnownMemberNames.EnumBackingFieldName;
}
}
+
+ internal override bool IsRequired => (Modifiers & DeclarationModifiers.Required) != 0;
}
internal abstract class SourceFieldSymbolWithSyntaxReference : SourceFieldSymbol
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
index 57b687b710fae..7a9ccdb3fcf06 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
@@ -1619,6 +1619,7 @@ protected void AfterMembersChecks(BindingDiagnosticBag diagnostics)
CheckSequentialOnPartialType(diagnostics);
CheckForProtectedInStaticClass(diagnostics);
CheckForUnmatchedOperators(diagnostics);
+ CheckForRequiredMembers(diagnostics);
var location = Locations[0];
var compilation = DeclaringCompilation;
@@ -2352,6 +2353,15 @@ private void CheckForEqualityAndGetHashCode(BindingDiagnosticBag diagnostics)
}
}
+ private void CheckForRequiredMembers(BindingDiagnosticBag diagnostics)
+ {
+ if (GetMembersUnordered().Any(SymbolExtensions.IsRequired))
+ {
+ // Ensure that an error is reported if the required constructor isn't present.
+ _ = Binder.GetWellKnownTypeMember(DeclaringCompilation, WellKnownMember.System_Runtime_CompilerServices_RequiredMembersAttribute__ctor, diagnostics, Locations[0]);
+ }
+ }
+
private bool TypeOverridesObjectMethod(string name)
{
foreach (var method in this.GetMembers(name).OfType())
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs
index 0911c864ce008..60b8c61a80f20 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs
@@ -712,6 +712,12 @@ private void CheckNewModifier(Symbol symbol, bool isNew, BindingDiagnosticBag di
AddHidingAbstractDiagnostic(symbol, symbolLocation, hiddenMember, diagnostics, ref unused);
+ if (hiddenMember.IsRequired())
+ {
+ // Required member '{0}' cannot be hidden by '{1}'.
+ diagnostics.Add(ErrorCode.ERR_RequiredMembersCannotBeHidden, symbolLocation, hiddenMember, symbol);
+ }
+
return;
}
}
@@ -900,6 +906,11 @@ void checkSingleOverriddenMember(Symbol overridingMember, Symbol overriddenMembe
// it is ok to override with no tuple names, for compatibility with C# 6, but otherwise names should match
diagnostics.Add(ErrorCode.ERR_CantChangeTupleNamesOnOverride, overridingMemberLocation, overridingMember, overriddenMember);
}
+ else if (overriddenMember is PropertySymbol { IsRequired: true } && overridingMember is PropertySymbol { IsRequired: false })
+ {
+ // '{0}': cannot remove 'required' from '{1}' when overriding
+ diagnostics.Add(ErrorCode.ERR_OverrideMustHaveRequired, overridingMemberLocation, overridingMember, overriddenMember);
+ }
else
{
// As in dev11, we don't compare obsoleteness to the immediately-overridden member,
@@ -1409,6 +1420,12 @@ private static void CheckNonOverrideMember(
diagnostics.Add(ErrorCode.WRN_NewOrOverrideExpected, hidingMemberLocation, hidingMember, hiddenMember);
diagnosticAdded = true;
}
+ else if (hiddenMember.IsRequired())
+ {
+ // Required member '{0}' cannot be hidden by '{1}'.
+ diagnostics.Add(ErrorCode.ERR_RequiredMembersCannotBeHidden, hidingMemberLocation, hiddenMember, hidingMember);
+ diagnosticAdded = true;
+ }
if (diagnosticAdded)
{
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
index cacbf6cb60e00..f654a111736ce 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
@@ -1110,7 +1110,16 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib
diagnostics.Add(ErrorCode.ERR_CantUseRequiredAttribute, arguments.AttributeSyntaxOpt.Name.Location);
}
else if (ReportExplicitUseOfReservedAttributes(in arguments,
- ReservedAttributes.DynamicAttribute | ReservedAttributes.IsReadOnlyAttribute | ReservedAttributes.IsUnmanagedAttribute | ReservedAttributes.IsByRefLikeAttribute | ReservedAttributes.TupleElementNamesAttribute | ReservedAttributes.NullableAttribute | ReservedAttributes.NullableContextAttribute | ReservedAttributes.NativeIntegerAttribute | ReservedAttributes.CaseSensitiveExtensionAttribute))
+ ReservedAttributes.DynamicAttribute
+ | ReservedAttributes.IsReadOnlyAttribute
+ | ReservedAttributes.IsUnmanagedAttribute
+ | ReservedAttributes.IsByRefLikeAttribute
+ | ReservedAttributes.TupleElementNamesAttribute
+ | ReservedAttributes.NullableAttribute
+ | ReservedAttributes.NullableContextAttribute
+ | ReservedAttributes.NativeIntegerAttribute
+ | ReservedAttributes.CaseSensitiveExtensionAttribute
+ | ReservedAttributes.RequiredMemberAttribute))
{
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.SecurityCriticalAttribute)
@@ -1583,6 +1592,39 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
AddSynthesizedAttribute(ref attributes,
this.DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
}
+
+ var requiredMembers = ArrayBuilder.GetInstance();
+ foreach (var member in GetMembers())
+ {
+ switch (member)
+ {
+ case SourceFieldSymbol { IsRequired: true }:
+ case SourcePropertySymbol { IsRequired: true, IsOverride: false }:
+ case SourcePropertySymbol { IsRequired: true, IsOverride: true, OverriddenProperty.IsRequired: false }:
+ requiredMembers.Add(member);
+ break;
+ }
+ }
+
+ if (requiredMembers.Any())
+ {
+ var stringType = compilation.GetSpecialType(SpecialType.System_String);
+ // Because GetMembers() is already sorted in lexical order, we don't need to do
+ // any additional sorting here.
+ var nameConstants = requiredMembers.SelectAsArray(
+ static (member, stringType) => new TypedConstant(stringType, TypedConstantKind.Primitive, member.Name),
+ stringType);
+ var stringArrayType = ArrayTypeSymbol.CreateSZArray(stringType.ContainingAssembly, TypeWithAnnotations.Create(stringType));
+
+ AddSynthesizedAttribute(
+ ref attributes,
+ compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_RequiredMembersAttribute__ctor,
+ ImmutableArray.Create(new TypedConstant(stringArrayType, nameConstants))));
+
+ // PROTOTYPE(req): Add obsolete marker to constructors if required members and Obsolete hasn't already been emitted
+ }
+
+ requiredMembers.Free();
}
#endregion
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs
index 17df109569781..26379673a21e5 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs
@@ -89,6 +89,7 @@ protected SourcePropertySymbolBase(
{
Debug.Assert(!isExpressionBodied || !isAutoProperty);
Debug.Assert(!isExpressionBodied || !hasInitializer);
+ Debug.Assert((modifiers & DeclarationModifiers.Required) == 0 || this is SourcePropertySymbol);
_syntaxRef = syntax.GetReference();
Location = location;
@@ -518,6 +519,8 @@ public override bool IsVirtual
get { return (_modifiers & DeclarationModifiers.Virtual) != 0; }
}
+ internal sealed override bool IsRequired => (_modifiers & DeclarationModifiers.Required) != 0;
+
internal bool IsNew
{
get { return (_modifiers & DeclarationModifiers.New) != 0; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs
index 14d0714f477eb..6c07312f1a32f 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs
@@ -1367,6 +1367,7 @@ internal enum ReservedAttributes
NullablePublicOnlyAttribute = 1 << 8,
NativeIntegerAttribute = 1 << 9,
CaseSensitiveExtensionAttribute = 1 << 10,
+ RequiredMemberAttribute = 1 << 11,
}
internal bool ReportExplicitUseOfReservedAttributes(in DecodeWellKnownAttributeArguments arguments, ReservedAttributes reserved)
@@ -1421,6 +1422,12 @@ internal bool ReportExplicitUseOfReservedAttributes(in DecodeWellKnownAttributeA
// ExtensionAttribute should not be set explicitly.
diagnostics.Add(ErrorCode.ERR_ExplicitExtension, arguments.AttributeSyntaxOpt.Location);
}
+ else if ((reserved & ReservedAttributes.RequiredMemberAttribute) != 0 &&
+ attribute.IsTargetAttribute(this, AttributeDescription.RequiredMembersAttribute))
+ {
+ // Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+ diagnostics.Add(ErrorCode.ERR_ExplicitRequiredMembers, arguments.AttributeSyntaxOpt.Location);
+ }
else
{
return false;
diff --git a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs
index 7a27991ad8521..e3229851e39d6 100644
--- a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs
@@ -839,5 +839,12 @@ internal static bool HasAsyncMethodBuilderAttribute(this Symbol symbol, [NotNull
builderArgument = null;
return false;
}
+
+ internal static bool IsRequired(this Symbol symbol)
+ => symbol switch
+ {
+ FieldSymbol { IsRequired: true } or PropertySymbol { IsRequired: true } => true,
+ _ => false
+ };
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs
index 6001d8b361c51..156c5ea333769 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs
@@ -151,5 +151,7 @@ private void CheckForFieldTargetedAttribute(BindingDiagnosticBag diagnostics)
}
}
}
+
+ internal override bool IsRequired => false;
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs
index 73a6dacbcf7ce..23b8a7b28a61c 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs
@@ -192,5 +192,7 @@ public override bool IsImplicitlyDeclared
{
get { return true; }
}
+
+ internal override bool IsRequired => false;
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs
index d623fd5268c5e..6bed480fef024 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedFieldSymbol.cs
@@ -204,5 +204,7 @@ public override bool IsStatic
return _underlyingField.IsStatic;
}
}
+
+ internal override bool IsRequired => _underlyingField.IsRequired;
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs
index e0ee3f5cdbbb8..1d2064b7410e8 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedPropertySymbol.cs
@@ -161,6 +161,8 @@ public override bool IsExtern
}
}
+ internal override bool IsRequired => _underlyingProperty.IsRequired;
+
internal override ObsoleteAttributeData ObsoleteAttributeData
{
get
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index b4d987d271105..3839b2d3e896c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -432,6 +432,11 @@
Přístupové objekty {0} a {1} by měly být buď oba jenom pro inicializaci, nebo ani jeden.
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Daný výraz nelze použít v příkazu fixed.
@@ -977,6 +982,11 @@
Metoda {0} určuje omezení default pro parametr typu {1}, ale odpovídající parametr typu {2} přepsané nebo explicitně implementované metody {3} není omezený na typ odkazu nebo hodnoty.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
Metoda {0} určuje omezení class pro parametr typu {1}, ale odpovídající parametr typu {2} přepsané nebo explicitně implementované metody {3} není odkazový typ.
@@ -1087,6 +1097,16 @@
Relační vzory se nedají použít pro hodnotu Není číslo s plovoucí desetinnou čárkou.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index a26a53dcb2ec7..89783b8f2df85 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -432,6 +432,11 @@
"init-only" muss entweder für beide oder für keine der Zugriffsmethoden "{0}" und "{1}" festgelegt sein.
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Der angegebene Ausdruck kann nicht in einer fixed-Anweisung verwendet werden.
@@ -977,6 +982,11 @@
Die Methode "{0}" gibt eine default-Einschränkung für den Typparameter "{1}" an, aber der zugehörige Typparameter "{2}" der überschriebenen oder explizit implementierten Methode "{3}" ist auf einen Verweistyp oder einen Werttyp beschränkt.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
Die Methode "{0}" gibt eine class-Einschränkung für den Typparameter "{1}" an, aber der zugehörige Typparameter "{2}" der außer Kraft gesetzten oder explizit implementierten Methode "{3}" ist kein Verweistyp.
@@ -1087,6 +1097,16 @@
Relationale Muster dürfen nicht für Gleitkomma-NaNs verwendet werden.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index e88006466b84a..d2f3f7759ce34 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -432,6 +432,11 @@
Los descriptores de acceso "{0}" y "{1}" deben ser los dos solo de inicialización o ninguno de ellos
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
La expresión proporcionada no se puede utilizar en una instrucción "fixed"
@@ -977,6 +982,11 @@
El método "{0}" especifica una restricción "default" para el parámetro de tipo "{1}", pero el parámetro de tipo "{2}" correspondiente del método "{3}" invalidado o implementado explícitamente se restringe a un tipo de referencia o a un tipo de valor.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
El método "{0}" especifica una restricción "class" para el parámetro de tipo "{1}", pero el parámetro de tipo correspondiente "{2}" de los métodos invalidados o implementados explícitamente "{3}" no es un tipo de referencia.
@@ -1087,6 +1097,16 @@
No se pueden usar patrones relacionales para un valor NaN de punto flotante.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 0e30ae0ddea5d..3a1922409a624 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -432,6 +432,11 @@
Les accesseurs '{0}' et '{1}' doivent tous deux être initialiseurs uniquement ou ne pas l'être
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Impossible d'utiliser l'expression donnée dans une instruction fixed
@@ -977,6 +982,11 @@
La méthode '{0}' spécifie une contrainte 'default' pour le paramètre de type '{1}', mais le paramètre de type '{2}' correspondant de la méthode substituée ou explicitement implémentée '{3}' est limité à un type référence ou à un type valeur.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
La méthode '{0}' spécifie une contrainte 'class' pour le paramètre de type '{1}', mais le paramètre de type '{2}' correspondant de la méthode substituée ou explicitement implémentée '{3}' n'est pas un type référence.
@@ -1087,6 +1097,16 @@
Les modèles relationnels ne peuvent pas être utilisés pour une valeur NaN à virgule flottante.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index a7835e3141be5..876d0de8aa0c2 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -432,6 +432,11 @@
Il tipo di sola inizializzazione può essere specificato per entrambe le funzioni di accesso '{0}' e '{1}' o per nessuna di esse
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Non è possibile usare l'espressione specificata in un'istruzione fixed
@@ -977,6 +982,11 @@
Il metodo '{0}' specifica un vincolo 'default' per il parametro di tipo '{1}', ma il parametro di tipo corrispondente '{2}' del metodo '{3}' sottoposto a override o implementato in modo esplicito è vincolato a un tipo riferimento a un tipo valore.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
Il metodo '{0}' specifica un vincolo 'class' per il parametro di tipo '{1}', ma il parametro di tipo corrispondente '{2}' del metodo '{3}' sottoposto a override o implementato in modo esplicito non è un tipo riferimento.
@@ -1087,6 +1097,16 @@
Non è possibile usare i criteri relazionali per un valore NaN a virgola mobile.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 78ebd039843a8..361d1431522a2 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -432,6 +432,11 @@
アクセサー '{0}' と '{1}' は、両方 init 専用か、両方そうでないかのいずれかでなければなりません
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
指定された式を fixed ステートメントで使用することはできません
@@ -977,6 +982,11 @@
メソッド '{0}' は、型パラメーター '{1}' に対して 'default' 制約を指定していますが、オーバーライドされた、または明示的に実装されたメソッド '{3}' の対応する型パラメーター '{2}' は、参照型または値の型に制約されています。
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
メソッド '{0}' は、型パラメーター '{1}' に対して 'class' 制約を指定していますが、オーバーライドされた、または明示的に実装されたメソッド '{3}' の対応する型パラメーター '{2}' は参照型ではありません。
@@ -1087,6 +1097,16 @@
リレーショナル パターンは、浮動小数点の NaN に使用することはできません。
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index d5fc12e260ebe..54db9f4a9cb80 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -432,6 +432,11 @@
'{0}' 및 '{1}' 접근자는 둘 다 초기값 전용이거나 둘 다 초기값 전용이 아니어야 합니다.
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
fixed 문에서는 지정된 식을 사용할 수 없습니다.
@@ -977,6 +982,11 @@
메서드 '{0}'이(가) 형식 매개 변수 '{1}'의 'default' 제약 조건을 지정하지만 재정의되었거나 명시적으로 구현된 메서드 '{3}'의 해당 형식 매개 변수 '{2}'이(가) 참조 형식 또는 값 형식으로 제한됩니다.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
'{0}' 메서드는 형식 매개 변수 '{1}'의 'class' 제약 조건을 지정하지만 재정의되었거나 명시적으로 구현된 '{3}' 메서드의 해당 형식 매개 변수 '{2}'이(가) 참조 형식이 아닙니다.
@@ -1087,6 +1097,16 @@
부동 소수점 NaN에는 관계형 패턴을 사용할 수 없습니다.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 1dfe4133834b8..1df1eab7f5e08 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -432,6 +432,11 @@
Tylko do inicjowania powinny być obie metody dostępu „{0}” i „{1}” albo żadna z nich
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Podanego wyrażenia nie można użyć w instrukcji fixed
@@ -977,6 +982,11 @@
Metoda „{0}” określa ograniczenie „default” dla parametru typu „{1}”, lecz odpowiadający parametr typu „{2}” przesłoniętej lub jawnie zaimplementowanej metody „{3}” jest ograniczony do typu odwołania lub typu wartości.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
Metoda „{0}” określa ograniczenie „class” dla parametru typu „{1}”, lecz odpowiadający parametr typu „{2}” przesłoniętej lub jawnie zaimplementowanej metody „{3}” nie jest typem referencyjnym.
@@ -1087,6 +1097,16 @@
Wzorców relacyjnych nie można używać na potrzeby zmiennoprzecinkowej wartości NaN.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 319272bc30954..2f1f82ade1a33 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -432,6 +432,11 @@
Os acessadores '{0}' e '{1}' devem ser somente de inicialização ou nenhum
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
A expressão determinada não pode ser usada em uma instrução fixed
@@ -977,6 +982,11 @@
O método '{0}' especifica uma restrição 'default' para o parâmetro de tipo '{1}', mas o parâmetro de tipo correspondente '{2}' do método substituído ou implementado explicitamente '{3}' está restrito por um tipo de referência ou um tipo de valor.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
O método '{0}' especifica uma restrição de 'class' para o parâmetro de tipo '{1}', mas o parâmetro de tipo correspondente '{2}' do método substituído ou implementado explicitamente '{3}' não é um tipo de referência.
@@ -1087,6 +1097,16 @@
Os padrões relacionais não podem ser usados para um NaN de ponto flutuante.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index feec841b41ff3..3575f8940b137 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -432,6 +432,11 @@
Каждый из методов доступа "{0}" и "{1}" должен вызываться только во время инициализации либо ни один из этих методов доступа не должен вызываться таким образом.
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Заданное выражение невозможно использовать в операторе fixed
@@ -977,6 +982,11 @@
Метод "{0}" задает ограничение "default" для параметра типа "{1}", но соответствующий параметр типа "{2}" переопределенного или явно реализованного метода "{3}" ограничен и может представлять собой только тип ссылки или тип значения.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
Метод "{0}" задает ограничение class для параметра типа "{1}", но соответствующий параметр типа "{2}" переопределенного или явно реализованного метода "{3}" не является ссылочным типом.
@@ -1087,6 +1097,16 @@
Реляционные шаблоны не могут использоваться для NaN с плавающей запятой.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 9fe8487a4efa5..688141c10c389 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -432,6 +432,11 @@
'{0}' ve '{1}' erişimcilerinin ikisi de yalnızca init olmalıdır ya da ikisi de olmamalıdır
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
Belirtilen ifade, fixed deyiminde kullanılamıyor
@@ -977,6 +982,11 @@
'{0}' metodu, '{1}' tür parametresi için bir 'default' kısıtlaması belirtiyor, ancak geçersiz kılınan veya açıkça uygulanan '{3}' metodunun karşılık gelen '{2}' tür parametresi bir başvuru türü veya değer türüyle kısıtlanmış.
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
'{0}' yöntemi, '{1}' tür parametresi için bir 'class' kısıtlaması belirtiyor, ancak geçersiz kılınan veya açıkça uygulanan '{3}' yönteminin karşılık gelen '{2}' tür parametresi bir başvuru türü değil.
@@ -1087,6 +1097,16 @@
İlişkisel desenler, kayan noktalı NaN için kullanılamaz.
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 5a48fd424489f..3d083e9066b9b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -432,6 +432,11 @@
访问器 {0} 和 {1} 应同时为 init-only,或两者都不是
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
给定表达式不能用于 fixed 语句中
@@ -977,6 +982,11 @@
方法“{0}”为类型参数“{1}”指定了 "default" 约束,但被替代的或显式实现的方法“{3}”的对应类型参数“{2}” 仅限于引用类型或值类型。
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
方法 "{0}" 为类型参数 "{1}" 指定了 "class" 约束,但重写的或显式实现的方法 "{3}" 的对应类型参数 "{2}" 不是引用类型。
@@ -1087,6 +1097,16 @@
关系模式可能不能用于浮点 NaN。
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index c05c909f7bc44..0de23b5db9925 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -432,6 +432,11 @@
存取子 '{0}' 與 '{1}' 不得同時是或不是僅供初始化
+
+
+ Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+
+
指定運算式無法用於 fixed 陳述式中
@@ -977,6 +982,11 @@
方法 '{0}' 會為型別參數 '{1}' 指定 'default' 條件約束,但覆寫或明確實作方法 '{3}' 的對應型別參數 '{2}' 會限制為參考型別或實值型別。
+
+
+ '{0}': cannot remove 'required' from '{1}' when overriding
+
+
方法 '{0}' 會為型別參數 '{1}' 指定 'class' 條件約束,但覆寫或明確實作的方法 '{3}' 對應型別參數 '{2}' 不屬於參考型別。
@@ -1087,6 +1097,16 @@
浮點 NaN 不可使用關聯性模式。
+
+
+ Required member '{0}' cannot be hidden by '{1}'.
+
+
+
+
+ Required member '{0}' cannot be less visible than the containing type '{1}'.
+
+
Types and aliases cannot not be named 'required'.
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs
index f1511be8f3a69..6876bb77c5da6 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs
@@ -610,6 +610,7 @@ public void AllWellKnownTypes()
case WellKnownType.System_Runtime_CompilerServices_NativeIntegerAttribute:
case WellKnownType.System_Runtime_CompilerServices_IsExternalInit:
case WellKnownType.System_Runtime_CompilerServices_DefaultInterpolatedStringHandler:
+ case WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute:
// Not yet in the platform.
continue;
case WellKnownType.Microsoft_CodeAnalysis_Runtime_Instrumentation:
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
index 6744ec9e860fd..f3687d968b369 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
@@ -11,10 +13,42 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols;
[CompilerTrait(CompilerFeature.RequiredMembers)]
public class RequiredMembersTests : CSharpTestBase
{
+ private const string RequiredMembersAttribute = @"
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
+ public class RequiredMembersAttribute : Attribute
+ {
+ public RequiredMembersAttribute(params string[] members)
+ {
+ this.Members = members;
+ }
+
+ public string[] Members { get; }
+ }
+}
+";
+
+ private CSharpCompilation CreateCompilationWithRequiredMembers(CSharpTestSource source, CSharpParseOptions? parseOptions = null, CSharpCompilationOptions? options = null)
+ => CreateCompilation(new[] { source, RequiredMembersAttribute }, options: options, parseOptions: parseOptions);
+
+ private Action ValidateRequiredMembersInModule(string[] memberPaths)
+ {
+ return module =>
+ {
+ foreach (var memberPath in memberPaths)
+ {
+ var member = module.GlobalNamespace.GetMember(memberPath);
+ Assert.True(member is PropertySymbol or FieldSymbol, $"Unexpected member symbol type {member.Kind}");
+ Assert.True(member.IsRequired());
+ }
+ };
+ }
+
[Fact]
public void InvalidModifierLocations()
{
- var comp = CreateCompilation(@"
+ var comp = CreateCompilationWithRequiredMembers(@"
required class C1
{
required void M(required int i)
@@ -104,7 +138,7 @@ class C2 : I2
[Fact]
public void InvalidModifierCombinations()
{
- var comp = CreateCompilation(@"
+ var comp = CreateCompilationWithRequiredMembers(@"
unsafe struct C
{
required const int F1 = 1;
@@ -136,48 +170,48 @@ unsafe struct C
[Fact]
public void LangVersion()
{
- var comp = CreateCompilation(@"
+ var comp = CreateCompilationWithRequiredMembers(@"
class C
{
- required int Field;
- required int Prop { get; set; }
+ internal required int Field;
+ internal required int Prop { get; set; }
}
", parseOptions: TestOptions.Regular10);
comp.VerifyDiagnostics(
- // (4,18): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
- // required int Field;
- Diagnostic(ErrorCode.ERR_FeatureInPreview, "Field").WithArguments("required members").WithLocation(4, 18),
- // (4,18): warning CS0169: The field 'C.Field' is never used
- // required int Field;
- Diagnostic(ErrorCode.WRN_UnreferencedField, "Field").WithArguments("C.Field").WithLocation(4, 18),
- // (5,18): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
- // required int Prop { get; set; }
- Diagnostic(ErrorCode.ERR_FeatureInPreview, "Prop").WithArguments("required members").WithLocation(5, 18)
+ // (4,27): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // internal required int Field;
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "Field").WithArguments("required members").WithLocation(4, 27),
+ // (4,27): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0
+ // internal required int Field;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(4, 27),
+ // (5,27): error CS8652: The feature 'required members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // internal required int Prop { get; set; }
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "Prop").WithArguments("required members").WithLocation(5, 27)
);
}
[Fact]
public void DuplicateKeyword()
{
- var comp = CreateCompilation(@"
+ var comp = CreateCompilationWithRequiredMembers(@"
class C
{
- required required int Field;
- required required int Prop { get; set; }
+ internal required required int Field;
+ internal required required int Prop { get; set; }
}
");
comp.VerifyDiagnostics(
- // (4,14): error CS1004: Duplicate 'required' modifier
- // required required int Field;
- Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(4, 14),
- // (4,27): warning CS0169: The field 'C.Field' is never used
- // required required int Field;
- Diagnostic(ErrorCode.WRN_UnreferencedField, "Field").WithArguments("C.Field").WithLocation(4, 27),
- // (5,14): error CS1004: Duplicate 'required' modifier
- // required required int Prop { get; set; }
- Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(5, 14)
+ // (4,23): error CS1004: Duplicate 'required' modifier
+ // internal required required int Field;
+ Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(4, 23),
+ // (4,36): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0
+ // internal required required int Field;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(4, 36),
+ // (5,23): error CS1004: Duplicate 'required' modifier
+ // internal required required int Prop { get; set; }
+ Diagnostic(ErrorCode.ERR_DuplicateModifier, "required").WithArguments("required").WithLocation(5, 23)
);
}
@@ -185,7 +219,7 @@ class C
[CombinatorialData]
public void InvalidNames(bool use10)
{
- var comp = CreateCompilation(@"
+ var comp = CreateCompilationWithRequiredMembers(@"
namespace N1
{
struct required {}
@@ -281,4 +315,766 @@ class required {}
}
);
}
+
+ [Fact]
+ public void MissingRequiredMembersAttribute()
+ {
+ var comp = CreateCompilation(@"
+class C
+{
+ public required int I { get; }
+}");
+
+ // (2,7): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiredMembersAttribute..ctor'
+ // class C
+ var expected = Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "C").WithArguments("System.Runtime.CompilerServices.RequiredMembersAttribute", ".ctor").WithLocation(2, 7);
+ comp.VerifyDiagnostics(expected);
+ comp.VerifyEmitDiagnostics(expected);
+ }
+
+ [Fact]
+ public void MissingRequiredMembersAttributeCtor()
+ {
+ var comp = CreateCompilation(@"
+class C
+{
+ public required int I { get; }
+}
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
+ public class RequiredMembersAttribute : Attribute
+ {
+ }
+}
+");
+
+ // (2,7): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.RequiredMembersAttribute..ctor'
+ // class C
+ var expected = Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "C").WithArguments("System.Runtime.CompilerServices.RequiredMembersAttribute", ".ctor").WithLocation(2, 7);
+ comp.VerifyDiagnostics(expected);
+ comp.VerifyEmitDiagnostics(expected);
+ }
+
+ [Fact]
+ public void RequiredMembersAttributeEmitted()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+class C
+{
+ public required int Prop { get; set; }
+ public required int Field;
+}
+");
+
+ var expectedRequiredMembers = new[] { "C.Prop", "C.Field" };
+
+ var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers));
+ verifier.VerifyDiagnostics(
+ // (5,25): warning CS0649: Field 'C.Field' is never assigned to, and will always have its default value 0
+ // public required int Field;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("C.Field", "0").WithLocation(5, 25)
+ );
+
+ verifier.VerifyTypeIL("C", @"
+.class private auto ansi beforefieldinit C
+ extends [netstandard]System.Object
+{
+ .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = (
+ 01 00 02 00 00 00 04 50 72 6f 70 05 46 69 65 6c
+ 64 00 00
+ )
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ .field public int32 Field
+ // Methods
+ .method public hidebysig specialname
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2050
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 C::'k__BackingField'
+ IL_0006: ret
+ } // end of method C::get_Prop
+ .method public hidebysig specialname
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2058
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 C::'k__BackingField'
+ IL_0007: ret
+ } // end of method C::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2061
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [netstandard]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method C::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 C::get_Prop()
+ .set instance void C::set_Prop(int32)
+ }
+} // end of class C
+");
+ }
+
+ [Fact]
+ public void RequiredMembersAttributeEmitted_OverrideRequiredProperty_MissingRequiredOnOverride()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+class Base
+{
+ public virtual required int Prop { get; set; }
+}
+class Dervied : Base
+{
+ public override int Prop { get; set; }
+}
+");
+
+ comp.VerifyDiagnostics(
+ // (8,25): error CS9501: 'Dervied.Prop': cannot remove 'required' from 'Base.Prop' when overriding
+ // public override int Prop { get; set; }
+ Diagnostic(ErrorCode.ERR_OverrideMustHaveRequired, "Prop").WithArguments("Dervied.Prop", "Base.Prop").WithLocation(8, 25)
+ );
+ }
+
+ [Fact]
+ public void RequiredMembersAttributeEmitted_OverrideRequiredProperty()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+class Base
+{
+ public virtual required int Prop { get; set; }
+}
+class Derived : Base
+{
+ public override required int Prop { get; set; }
+}
+");
+
+ var expectedRequiredMembers = new[] { "Base.Prop", "Derived.Prop" };
+
+ var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers));
+ verifier.VerifyDiagnostics();
+
+ verifier.VerifyTypeIL("Base", @"
+.class private auto ansi beforefieldinit Base
+ extends [netstandard]System.Object
+{
+ .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = (
+ 01 00 01 00 00 00 04 50 72 6f 70 00 00
+ )
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Methods
+ .method public hidebysig specialname newslot virtual
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2050
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 Base::'k__BackingField'
+ IL_0006: ret
+ } // end of method Base::get_Prop
+ .method public hidebysig specialname newslot virtual
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2058
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 Base::'k__BackingField'
+ IL_0007: ret
+ } // end of method Base::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2061
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [netstandard]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Base::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 Base::get_Prop()
+ .set instance void Base::set_Prop(int32)
+ }
+} // end of class Base
+");
+
+ verifier.VerifyTypeIL("Derived", @"
+.class private auto ansi beforefieldinit Derived
+ extends Base
+{
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Methods
+ .method public hidebysig specialname virtual
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2069
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 Derived::'k__BackingField'
+ IL_0006: ret
+ } // end of method Derived::get_Prop
+ .method public hidebysig specialname virtual
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2071
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 Derived::'k__BackingField'
+ IL_0007: ret
+ } // end of method Derived::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x207a
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void Base::.ctor()
+ IL_0006: ret
+ } // end of method Derived::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 Derived::get_Prop()
+ .set instance void Derived::set_Prop(int32)
+ }
+} // end of class Derived
+");
+ }
+
+ [Fact]
+ public void RequiredMembersAttributeEmitted_AddRequiredOnOverride()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+class Base
+{
+ public virtual int Prop { get; set; }
+}
+class Derived : Base
+{
+ public override required int Prop { get; set; }
+}
+class DerivedDerived : Derived
+{
+ public override required int Prop { get; set; }
+}
+");
+
+ var expectedRequiredMembers = new[] { "Derived.Prop", "DerivedDerived.Prop" };
+
+ var verifier = CompileAndVerify(comp, sourceSymbolValidator: ValidateRequiredMembersInModule(expectedRequiredMembers));
+ verifier.VerifyDiagnostics();
+
+ verifier.VerifyTypeIL("Base", @"
+.class private auto ansi beforefieldinit Base
+ extends [netstandard]System.Object
+{
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Methods
+ .method public hidebysig specialname newslot virtual
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2050
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 Base::'k__BackingField'
+ IL_0006: ret
+ } // end of method Base::get_Prop
+ .method public hidebysig specialname newslot virtual
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2058
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 Base::'k__BackingField'
+ IL_0007: ret
+ } // end of method Base::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2061
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [netstandard]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Base::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 Base::get_Prop()
+ .set instance void Base::set_Prop(int32)
+ }
+} // end of class Base
+");
+
+ verifier.VerifyTypeIL("Derived", @"
+.class private auto ansi beforefieldinit Derived
+ extends Base
+{
+ .custom instance void System.Runtime.CompilerServices.RequiredMembersAttribute::.ctor(string[]) = (
+ 01 00 01 00 00 00 04 50 72 6f 70 00 00
+ )
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Methods
+ .method public hidebysig specialname virtual
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2069
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 Derived::'k__BackingField'
+ IL_0006: ret
+ } // end of method Derived::get_Prop
+ .method public hidebysig specialname virtual
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2071
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 Derived::'k__BackingField'
+ IL_0007: ret
+ } // end of method Derived::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x207a
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void Base::.ctor()
+ IL_0006: ret
+ } // end of method Derived::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 Derived::get_Prop()
+ .set instance void Derived::set_Prop(int32)
+ }
+} // end of class Derived
+");
+
+ verifier.VerifyTypeIL("DerivedDerived", @"
+.class private auto ansi beforefieldinit DerivedDerived
+ extends Derived
+{
+ // Fields
+ .field private int32 'k__BackingField'
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Methods
+ .method public hidebysig specialname virtual
+ instance int32 get_Prop () cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x2082
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld int32 DerivedDerived::'k__BackingField'
+ IL_0006: ret
+ } // end of method DerivedDerived::get_Prop
+ .method public hidebysig specialname virtual
+ instance void set_Prop (
+ int32 'value'
+ ) cil managed
+ {
+ .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
+ 01 00 00 00
+ )
+ // Method begins at RVA 0x208a
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stfld int32 DerivedDerived::'k__BackingField'
+ IL_0007: ret
+ } // end of method DerivedDerived::set_Prop
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2093
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void Derived::.ctor()
+ IL_0006: ret
+ } // end of method DerivedDerived::.ctor
+ // Properties
+ .property instance int32 Prop()
+ {
+ .get instance int32 DerivedDerived::get_Prop()
+ .set instance void DerivedDerived::set_Prop(int32)
+ }
+} // end of class DerivedDerived
+");
+ }
+
+ [Fact]
+ public void HidingRequiredMembers()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+#pragma warning disable CS0649 // Never assigned
+class Base
+{
+ public required int Field;
+ public required int Prop { get; set; }
+}
+class Derived1 : Base
+{
+ public new int Field; // 1
+ public new int Prop { get; set; } // 2
+}
+class Derived2 : Base
+{
+ public new int Prop; // 3
+ public new int Field { get; set; } // 4
+}
+");
+
+ comp.VerifyDiagnostics(
+ // (10,20): error CS9502: Required member 'Base.Field' cannot be hidden by 'Derived1.Field'.
+ // public new int Field; // 1
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Field").WithArguments("Base.Field", "Derived1.Field").WithLocation(10, 20),
+ // (11,20): error CS9502: Required member 'Base.Prop' cannot be hidden by 'Derived1.Prop'.
+ // public new int Prop { get; set; } // 2
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Prop").WithArguments("Base.Prop", "Derived1.Prop").WithLocation(11, 20),
+ // (15,20): error CS9502: Required member 'Base.Prop' cannot be hidden by 'Derived2.Prop'.
+ // public new int Prop; // 3
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Prop").WithArguments("Base.Prop", "Derived2.Prop").WithLocation(15, 20),
+ // (16,20): error CS9502: Required member 'Base.Field' cannot be hidden by 'Derived2.Field'.
+ // public new int Field { get; set; } // 4
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeHidden, "Field").WithArguments("Base.Field", "Derived2.Field").WithLocation(16, 20)
+ );
+ }
+
+ [Fact]
+ public void RequiredMembersMustBeAsVisibleAsContainingType()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+#pragma warning disable CS0649 // Never assigned
+#pragma warning disable CS0169 // Never used
+public class C1
+{
+ public required int Prop1 { get; set; }
+ internal protected required int Prop2 { get; set; }
+ internal required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal protected required int Field2;
+ internal required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+}
+internal class C2
+{
+ public required int Prop1 { get; set; }
+ internal protected required int Prop2 { get; set; }
+ internal required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal protected required int Field2;
+ internal required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+}
+internal class Outer
+{
+ protected internal class C3
+ {
+ public required int Prop1 { get; set; }
+ internal required int Prop2 { get; set; }
+ internal protected required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal required int Field2;
+ internal protected required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+ }
+ protected class C4
+ {
+ public required int Prop1 { get; set; }
+ internal protected required int Prop2 { get; set; }
+ internal required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal protected required int Field2;
+ internal required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+ }
+ private protected class C5
+ {
+ public required int Prop1 { get; set; }
+ internal protected required int Prop2 { get; set; }
+ internal required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal protected required int Field2;
+ internal required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+ }
+ private class C6
+ {
+ public required int Prop1 { get; set; }
+ internal protected required int Prop2 { get; set; }
+ internal required int Prop3 { get; set; }
+ protected required int Prop4 { get; set; }
+ private protected required int Prop5 { get; set; }
+ private required int Prop6 { get; set; }
+ public required int Field1;
+ internal protected required int Field2;
+ internal required int Field3;
+ protected required int Field4;
+ private protected required int Field5;
+ private required int Field6;
+ }
+}
+");
+
+ comp.VerifyDiagnostics(
+ // (7,37): error CS9503: Required member 'C1.Prop2' cannot be less visible than the containing type 'C1'.
+ // internal protected required int Prop2 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("C1.Prop2", "C1").WithLocation(7, 37),
+ // (8,27): error CS9503: Required member 'C1.Prop3' cannot be less visible than the containing type 'C1'.
+ // internal required int Prop3 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop3").WithArguments("C1.Prop3", "C1").WithLocation(8, 27),
+ // (9,28): error CS9503: Required member 'C1.Prop4' cannot be less visible than the containing type 'C1'.
+ // protected required int Prop4 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("C1.Prop4", "C1").WithLocation(9, 28),
+ // (10,36): error CS9503: Required member 'C1.Prop5' cannot be less visible than the containing type 'C1'.
+ // private protected required int Prop5 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("C1.Prop5", "C1").WithLocation(10, 36),
+ // (11,26): error CS9503: Required member 'C1.Prop6' cannot be less visible than the containing type 'C1'.
+ // private required int Prop6 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("C1.Prop6", "C1").WithLocation(11, 26),
+ // (13,37): error CS9503: Required member 'C1.Field2' cannot be less visible than the containing type 'C1'.
+ // internal protected required int Field2;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field2").WithArguments("C1.Field2", "C1").WithLocation(13, 37),
+ // (14,27): error CS9503: Required member 'C1.Field3' cannot be less visible than the containing type 'C1'.
+ // internal required int Field3;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field3").WithArguments("C1.Field3", "C1").WithLocation(14, 27),
+ // (15,28): error CS9503: Required member 'C1.Field4' cannot be less visible than the containing type 'C1'.
+ // protected required int Field4;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("C1.Field4", "C1").WithLocation(15, 28),
+ // (16,36): error CS9503: Required member 'C1.Field5' cannot be less visible than the containing type 'C1'.
+ // private protected required int Field5;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("C1.Field5", "C1").WithLocation(16, 36),
+ // (17,26): error CS9503: Required member 'C1.Field6' cannot be less visible than the containing type 'C1'.
+ // private required int Field6;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("C1.Field6", "C1").WithLocation(17, 26),
+ // (24,28): error CS9503: Required member 'C2.Prop4' cannot be less visible than the containing type 'C2'.
+ // protected required int Prop4 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("C2.Prop4", "C2").WithLocation(24, 28),
+ // (25,36): error CS9503: Required member 'C2.Prop5' cannot be less visible than the containing type 'C2'.
+ // private protected required int Prop5 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("C2.Prop5", "C2").WithLocation(25, 36),
+ // (26,26): error CS9503: Required member 'C2.Prop6' cannot be less visible than the containing type 'C2'.
+ // private required int Prop6 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("C2.Prop6", "C2").WithLocation(26, 26),
+ // (30,28): error CS9503: Required member 'C2.Field4' cannot be less visible than the containing type 'C2'.
+ // protected required int Field4;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("C2.Field4", "C2").WithLocation(30, 28),
+ // (31,36): error CS9503: Required member 'C2.Field5' cannot be less visible than the containing type 'C2'.
+ // private protected required int Field5;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("C2.Field5", "C2").WithLocation(31, 36),
+ // (32,26): error CS9503: Required member 'C2.Field6' cannot be less visible than the containing type 'C2'.
+ // private required int Field6;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("C2.Field6", "C2").WithLocation(32, 26),
+ // (39,31): error CS9503: Required member 'Outer.C3.Prop2' cannot be less visible than the containing type 'Outer.C3'.
+ // internal required int Prop2 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("Outer.C3.Prop2", "Outer.C3").WithLocation(39, 31),
+ // (41,32): error CS9503: Required member 'Outer.C3.Prop4' cannot be less visible than the containing type 'Outer.C3'.
+ // protected required int Prop4 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop4").WithArguments("Outer.C3.Prop4", "Outer.C3").WithLocation(41, 32),
+ // (42,40): error CS9503: Required member 'Outer.C3.Prop5' cannot be less visible than the containing type 'Outer.C3'.
+ // private protected required int Prop5 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("Outer.C3.Prop5", "Outer.C3").WithLocation(42, 40),
+ // (43,30): error CS9503: Required member 'Outer.C3.Prop6' cannot be less visible than the containing type 'Outer.C3'.
+ // private required int Prop6 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C3.Prop6", "Outer.C3").WithLocation(43, 30),
+ // (45,31): error CS9503: Required member 'Outer.C3.Field2' cannot be less visible than the containing type 'Outer.C3'.
+ // internal required int Field2;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field2").WithArguments("Outer.C3.Field2", "Outer.C3").WithLocation(45, 31),
+ // (47,32): error CS9503: Required member 'Outer.C3.Field4' cannot be less visible than the containing type 'Outer.C3'.
+ // protected required int Field4;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field4").WithArguments("Outer.C3.Field4", "Outer.C3").WithLocation(47, 32),
+ // (48,40): error CS9503: Required member 'Outer.C3.Field5' cannot be less visible than the containing type 'Outer.C3'.
+ // private protected required int Field5;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("Outer.C3.Field5", "Outer.C3").WithLocation(48, 40),
+ // (49,30): error CS9503: Required member 'Outer.C3.Field6' cannot be less visible than the containing type 'Outer.C3'.
+ // private required int Field6;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C3.Field6", "Outer.C3").WithLocation(49, 30),
+ // (57,40): error CS9503: Required member 'Outer.C4.Prop5' cannot be less visible than the containing type 'Outer.C4'.
+ // private protected required int Prop5 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop5").WithArguments("Outer.C4.Prop5", "Outer.C4").WithLocation(57, 40),
+ // (58,30): error CS9503: Required member 'Outer.C4.Prop6' cannot be less visible than the containing type 'Outer.C4'.
+ // private required int Prop6 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C4.Prop6", "Outer.C4").WithLocation(58, 30),
+ // (63,40): error CS9503: Required member 'Outer.C4.Field5' cannot be less visible than the containing type 'Outer.C4'.
+ // private protected required int Field5;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field5").WithArguments("Outer.C4.Field5", "Outer.C4").WithLocation(63, 40),
+ // (64,30): error CS9503: Required member 'Outer.C4.Field6' cannot be less visible than the containing type 'Outer.C4'.
+ // private required int Field6;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C4.Field6", "Outer.C4").WithLocation(64, 30),
+ // (73,30): error CS9503: Required member 'Outer.C5.Prop6' cannot be less visible than the containing type 'Outer.C5'.
+ // private required int Prop6 { get; set; }
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Prop6").WithArguments("Outer.C5.Prop6", "Outer.C5").WithLocation(73, 30),
+ // (79,30): error CS9503: Required member 'Outer.C5.Field6' cannot be less visible than the containing type 'Outer.C5'.
+ // private required int Field6;
+ Diagnostic(ErrorCode.ERR_RequiredMembersCannotBeLessVisibleThanContainingType, "Field6").WithArguments("Outer.C5.Field6", "Outer.C5").WithLocation(79, 30)
+ );
+ }
+
+ [Fact]
+ public void RequiredMembersCannotBeExplicitInterfaceImplementations()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+interface I
+{
+ int Prop { get; set; }
+}
+class C : I
+{
+ required int I.Prop { get; set; }
+}
+");
+
+ comp.VerifyDiagnostics(
+ // (8,20): error CS0106: The modifier 'required' is not valid for this item
+ // required int I.Prop { get; set; }
+ Diagnostic(ErrorCode.ERR_BadMemberFlag, "Prop").WithArguments("required").WithLocation(8, 20)
+ );
+ }
+
+ [Fact]
+ public void UsingRequiredMembersAttributeExplicitly()
+ {
+ var comp = CreateCompilationWithRequiredMembers(@"
+using System.Runtime.CompilerServices;
+[RequiredMembers(new[] { ""Prop"" })]
+class C
+{
+ public int Prop { get; set; }
+}
+");
+
+ comp.VerifyDiagnostics(
+ // (3,2): error CS9504: Do not use 'System.Runtime.CompilerSerives.RequiredMembersAttribute'. Use the 'required' keyword on required fields and properties instead.
+ // [RequiredMembers(new[] { "Prop" })]
+ Diagnostic(ErrorCode.ERR_ExplicitRequiredMembers, @"RequiredMembers(new[] { ""Prop"" })").WithLocation(3, 2)
+ );
+
+ var prop = comp.SourceModule.GlobalNamespace.GetMember("C.Prop");
+ Assert.False(prop.IsRequired);
+ }
}
diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs
index a4704092eb521..e7e6bd0a97824 100644
--- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs
+++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs
@@ -1127,6 +1127,7 @@ internal ObsoleteAttributeData TryGetDeprecatedOrExperimentalOrObsoleteAttribute
ObsoleteAttributeData obsoleteData = TryExtractObsoleteDataFromAttribute(info, decoder);
switch (obsoleteData?.Message)
{
+ // PROTOTYPE(req): Ignore required obsolete marker
case ByRefLikeMarker when ignoreByRefLikeMarker:
return null;
}
diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs
index 4dc73d5a53282..292669e9d8219 100644
--- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs
+++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs
@@ -199,6 +199,7 @@ static AttributeDescription()
private static readonly byte[][] s_signatures_HasThis_Void_Only = { s_signature_HasThis_Void };
private static readonly byte[][] s_signatures_HasThis_Void_String_Only = { s_signature_HasThis_Void_String };
+ private static readonly byte[][] s_signatures_HasThis_Void_SzArray_String_Only = { s_signature_HasThis_Void_SzArray_String };
private static readonly byte[][] s_signatures_HasThis_Void_Type_Only = { s_signature_HasThis_Void_Type };
private static readonly byte[][] s_signatures_HasThis_Void_Boolean_Only = { s_signature_HasThis_Void_Boolean };
@@ -478,5 +479,6 @@ static AttributeDescription()
internal static readonly AttributeDescription UnmanagedCallersOnlyAttribute = new AttributeDescription("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute", s_signatures_HasThis_Void_Only);
internal static readonly AttributeDescription InterpolatedStringHandlerAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterpolatedStringHandlerAttribute", s_signatures_HasThis_Void_Only);
internal static readonly AttributeDescription InterpolatedStringHandlerArgumentAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterpolatedStringHandlerArgumentAttribute", s_signaturesOfInterpolatedStringArgumentAttribute);
+ internal static readonly AttributeDescription RequiredMembersAttribute = new AttributeDescription("System.Runtime.CompilerServices", "RequiredMembersAttribute", s_signatures_HasThis_Void_SzArray_String_Only);
}
}
diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs
index b8ce5205655ec..b17789a712872 100644
--- a/src/Compilers/Core/Portable/WellKnownMember.cs
+++ b/src/Compilers/Core/Portable/WellKnownMember.cs
@@ -517,6 +517,9 @@ internal enum WellKnownMember
System_Runtime_CompilerServices_DefaultInterpolatedStringHandler__ToStringAndClear,
+ System_Runtime_CompilerServices_RequiredMembersAttribute__ctor,
+ System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members,
+
Count
// Remember to update the AllWellKnownTypeMembers tests when making changes here
diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs
index 00f6ae1bcf8a4..b2f9570027bf1 100644
--- a/src/Compilers/Core/Portable/WellKnownMembers.cs
+++ b/src/Compilers/Core/Portable/WellKnownMembers.cs
@@ -3535,6 +3535,21 @@ static WellKnownMembers()
0, // Method Signature
(byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Return Type
+ // System_Runtime_CompilerServices_RequiredMembersAttribute__ctor
+ (byte)MemberFlags.Constructor, // Flags
+ (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId
+ 0, // Arity
+ 1, // Method Signature
+ (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type
+ (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String,
+
+ // System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members
+ (byte)(MemberFlags.PropertyGet | MemberFlags.Static), // Flags
+ (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_RequiredMembersAttribute - WellKnownType.ExtSentinel), // DeclaringTypeId
+ 0, // Arity
+ 0, // Method Signature
+ (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.TypeHandle, (byte)WellKnownType.System_Collections_Generic_EqualityComparer_T,// Return Type
+
};
string[] allNames = new string[(int)WellKnownMember.Count]
@@ -3979,6 +3994,8 @@ static WellKnownMembers()
"Append", // System_Text_StringBuilder__AppendObject
".ctor", // System_Text_StringBuilder__ctor
"ToStringAndClear", // System_Runtime_CompilerServices_DefaultInterpolatedStringHandler__ToStringAndClear
+ ".ctor", // System_Runtime_CompilerServices_RequiredMembersAttribute__ctor
+ "get_Members", // System_Runtime_CompilerServices_RequiredMembersAttribute__get_Members
};
s_descriptors = MemberDescriptor.InitializeFromStream(new System.IO.MemoryStream(initializationBytes, writable: false), allNames);
diff --git a/src/Compilers/Core/Portable/WellKnownTypes.cs b/src/Compilers/Core/Portable/WellKnownTypes.cs
index 1ee9254677987..5962d69453a08 100644
--- a/src/Compilers/Core/Portable/WellKnownTypes.cs
+++ b/src/Compilers/Core/Portable/WellKnownTypes.cs
@@ -317,6 +317,8 @@ internal enum WellKnownType
System_ArgumentNullException,
+ System_Runtime_CompilerServices_RequiredMembersAttribute,
+
NextAvailable,
// Remember to update the AllWellKnownTypes tests when making changes here
}
@@ -625,6 +627,8 @@ internal static class WellKnownTypes
"System.Text.StringBuilder",
"System.Runtime.CompilerServices.DefaultInterpolatedStringHandler",
"System.ArgumentNullException",
+
+ "System.Runtime.CompilerServices.RequiredMembersAttribute"
};
private static readonly Dictionary s_nameToTypeIdMap = new Dictionary((int)Count);
diff --git a/src/Compilers/Test/Core/CompilationVerifier.cs b/src/Compilers/Test/Core/CompilationVerifier.cs
index 1ed62d8b828c8..a23902e55a141 100644
--- a/src/Compilers/Test/Core/CompilationVerifier.cs
+++ b/src/Compilers/Test/Core/CompilationVerifier.cs
@@ -193,7 +193,7 @@ public void VerifyTypeIL(string typeName, string expected)
Assert.True(found, "Could not find type named " + typeName);
}
}
- AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString(), escapeQuotes: false);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString().Replace("\t", " "), escapeQuotes: false);
}
public void Emit(string expectedOutput, int? expectedReturnCode, string[] args, IEnumerable manifestResources, EmitOptions emitOptions, Verification peVerify, SignatureDescription[] expectedSignatures)
diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs
index d04f935e73e1a..a175df54f20b1 100644
--- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs
+++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/DisplayClassVariable.cs
@@ -159,6 +159,8 @@ public override bool IsVolatile
get { return false; }
}
+ public override bool IsRequired => throw ExceptionUtilities.Unreachable;
+
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
{
get { return FlowAnalysisAnnotations.None; }