diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 25a71e7c1cf6a..f69ab0f465c8a 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7136,6 +7136,15 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ '{0}' requires compiler feature '{1}', which is not supported by this version of the C# compiler. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + + Ref returning properties cannot be required. + Unexpected keyword 'unchecked' diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 599214e3c08c2..6a9fcdad67492 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2089,5 +2089,7 @@ internal enum ErrorCode ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers = 9510, ERR_NewConstraintCannotHaveRequiredMembers = 9511, ERR_UnsupportedCompilerFeature = 9512, + WRN_ObsoleteMembersShouldNotBeRequired = 9513, + ERR_RefReturningPropertiesCannotBeRequired = 9514, } } diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index d427a18300a58..0d2b3b40fec37 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -501,6 +501,7 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_UseDefViolationThisSupportedVersion: case ErrorCode.WRN_UnassignedThisAutoPropertySupportedVersion: case ErrorCode.WRN_UnassignedThisSupportedVersion: + case ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired: return 1; default: return 0; diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index b0c58cadf4247..8bbb62928ab1d 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -676,7 +676,7 @@ void checkMemberStateOnConstructorExit(MethodSymbol constructor, Symbol member, return; } - if (symbol.IsRequired()) + if (symbol.IsRequired() && constructor.ShouldCheckRequiredMembers()) { return; } diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index f4b635dc89759..4767b0fdbf588 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -289,6 +289,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_UseDefViolationThisSupportedVersion: case ErrorCode.WRN_UnassignedThisAutoPropertySupportedVersion: case ErrorCode.WRN_UnassignedThisSupportedVersion: + case ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs b/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs index db5bf7a0a20f3..c69369a4361fa 100644 --- a/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs +++ b/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs @@ -49,15 +49,16 @@ internal enum CompletionPart SynthesizedExplicitImplementations = 1 << 13, StartMemberChecks = 1 << 14, FinishMemberChecks = 1 << 15, - MembersCompleted = 1 << 16, // this should be the last (highest-value) part + MembersCompletedChecksStarted = 1 << 16, + MembersCompleted = 1 << 17, // this should be the last (highest-value) part - All = (1 << 17) - 1, + All = (1 << 18) - 1, // This is the work we can do if ForceComplete is scoped to a particular SyntaxTree. NamedTypeSymbolWithLocationAll = Attributes | StartBaseType | FinishBaseType | StartInterfaces | FinishInterfaces | EnumUnderlyingType | TypeArguments | TypeParameters | Members | TypeMembers | SynthesizedExplicitImplementations | StartMemberChecks | FinishMemberChecks, - NamedTypeSymbolAll = NamedTypeSymbolWithLocationAll | MembersCompleted, + NamedTypeSymbolAll = NamedTypeSymbolWithLocationAll | MembersCompletedChecksStarted | MembersCompleted, // For Usings StartValidatingImports = 1 << 4, diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs index d3bd015bee4ec..34410c9291708 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs @@ -244,6 +244,8 @@ internal override LexicalSortKey GetLexicalSortKey() // so we will keep them the same. return new LexicalSortKey(this.syntaxReferenceOpt.GetLocation(), this.DeclaringCompilation); } + + protected override bool HasSetsRequiredMembersImpl => false; } private sealed class InvokeMethod : SourceDelegateMethodSymbol diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index c979a69dc7ecc..1cc6f1f986183 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -598,6 +598,7 @@ internal override void ForceComplete(SourceLocation? locationOpt, CancellationTo } break; + case CompletionPart.MembersCompletedChecksStarted: case CompletionPart.MembersCompleted: { ImmutableArray members = this.GetMembersUnordered(); @@ -631,12 +632,22 @@ internal override void ForceComplete(SourceLocation? locationOpt, CancellationTo } EnsureFieldDefinitionsNoted(); + cancellationToken.ThrowIfCancellationRequested(); - // We've completed all members, so we're ready for the PointedAtManagedTypeChecks; - // proceed to the next iteration. - state.NotePartComplete(CompletionPart.MembersCompleted); - break; + if (state.NotePartComplete(CompletionPart.MembersCompletedChecksStarted)) + { + var diagnostics = BindingDiagnosticBag.GetInstance(); + AfterMembersCompletedChecks(diagnostics); + AddDeclarationDiagnostics(diagnostics); + + // We've completed all members, so we're ready for the PointedAtManagedTypeChecks; + // proceed to the next iteration. + var thisThreadCompleted = state.NotePartComplete(CompletionPart.MembersCompleted); + Debug.Assert(thisThreadCompleted); + diagnostics.Free(); + } } + break; case CompletionPart.None: return; @@ -1744,6 +1755,10 @@ static bool needsTupleElementNamesAttribute(TypeSymbol type) } } + protected virtual void AfterMembersCompletedChecks(BindingDiagnosticBag diagnostics) + { + } + private void CheckMemberNamesDistinctFromType(BindingDiagnosticBag diagnostics) { foreach (var member in GetMembersAndInitializers().NonTypeMembers) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs index aba7d243e2240..49acec15bccbe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs @@ -199,7 +199,6 @@ internal static DeclarationModifiers MakeModifiers(NamedTypeSymbol containingTyp if ((result & DeclarationModifiers.Required) != 0) { - // PROTOTYPE(req): capture the allowed modifier combinations in the specification // The modifier 'required' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.RequiredKeyword)); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index 65cfa1b1b8289..7b0b8baf70e3e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -1638,5 +1638,42 @@ internal bool IsSimpleProgram return this.declaration.Declarations.Any(d => d.IsSimpleProgram); } } + + protected override void AfterMembersCompletedChecks(BindingDiagnosticBag diagnostics) + { + base.AfterMembersCompletedChecks(diagnostics); + + // We need to give warnings if Obsolete is applied to any required members and there are constructors where a user would be forced to set that member, + // unless: + // 1. We're in an obsolete context ourselves, or + // 2. All constructors of this type are obsolete or attributed with SetsRequiredMembersAttribute + // We don't warn for obsolete required members from base types, as the user either has a warning that they're depending on an obsolete constructor/type + // already, or the original author ignored this warning. + + // Obsolete states should have already been calculated by this point in the pipeline. + Debug.Assert(ObsoleteKind != ObsoleteAttributeKind.Uninitialized); + Debug.Assert(GetMembers().All(m => m.ObsoleteKind != ObsoleteAttributeKind.Uninitialized)); + + if (ObsoleteKind != ObsoleteAttributeKind.None + || GetMembers().All(m => m is not MethodSymbol { MethodKind: MethodKind.Constructor, ObsoleteKind: ObsoleteAttributeKind.None } method + || !method.ShouldCheckRequiredMembers())) + { + return; + } + + foreach (var member in GetMembers()) + { + if (!member.IsRequired()) + { + continue; + } + + if (member.ObsoleteKind != ObsoleteAttributeKind.None) + { + // Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + diagnostics.Add(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, member.Locations[0], member); + } + } + } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index 9ec1be22c332d..d136fe32d4007 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -677,6 +677,12 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, CheckInitializer(IsAutoProperty, ContainingType.IsInterface, IsStatic, Location, diagnostics); } + if (RefKind != RefKind.None && IsRequired) + { + // Ref returning properties cannot be required. + diagnostics.Add(ErrorCode.ERR_RefReturningPropertiesCannotBeRequired, Location); + } + if (IsAutoPropertyWithGetAccessor) { Debug.Assert(GetMethod is object); diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 797ba91a87918..1d962dd073c16 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -1207,6 +1207,11 @@ Levá strana přiřazení odkazu musí být lokální proměnná nebo parametr odkazu. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Relační vzory se nedají použít pro hodnotu Není číslo s plovoucí desetinnou čárkou. @@ -1822,6 +1827,16 @@ Typ s možnou hodnotou null je zaškrtnut hodnotou null a vyvolá se při hodnotě null. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. Parametr {0} musí mít při ukončení hodnotu jinou než null, protože parametr {1} není null. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index a87fa23a6ce66..a20a028ef6e3d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -1207,6 +1207,11 @@ Die linke Seite einer ref-Zuweisung muss ein lokaler Verweis oder ein Parameter sein. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Relationale Muster dürfen nicht für Gleitkomma-NaNs verwendet werden. @@ -1822,6 +1827,16 @@ Der Nullable-Typ wurde auf NULL-Werte überprüft und wird bei NULL ausgelöst. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. Der Parameter "{0}" muss beim Beenden einen Wert ungleich NULL aufweisen, weil Parameter "{1}" nicht NULL ist. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index a6ebebc74305b..4d541b16bb4bc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -1207,6 +1207,11 @@ La parte izquierda de una asignación de referencias debe ser una referencia local o un parámetro. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. No se pueden usar patrones relacionales para un valor NaN de punto flotante. @@ -1822,6 +1827,16 @@ El tipo que acepta valores NULL está activado con valor NULL y se iniciará si es null. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. El parámetro "{0}" debe tener un valor que no sea NULL al salir porque el parámetro "{1}" no es NULL. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index ccc6df16346b9..db0c226e4a872 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -1207,6 +1207,11 @@ La partie gauche d'une assignation par référence doit être une variable locale ou un paramètre ref. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Les modèles relationnels ne peuvent pas être utilisés pour une valeur NaN à virgule flottante. @@ -1822,6 +1827,16 @@ Le type Nullable est activé pour null et lèvera si null. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. Le paramètre '{0}' doit avoir une valeur non null au moment de la sortie, car le paramètre '{1}' a une valeur non null. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 4fd1ecc7c49a5..af0758a6db8ce 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -1207,6 +1207,11 @@ La parte sinistra di un'assegnazione ref deve essere un parametro o una variabile locale ref. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Non è possibile usare i criteri relazionali per un valore NaN a virgola mobile. @@ -1822,6 +1827,16 @@ Il tipo nullable è controllato Null e verrà generato se Null. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. Il parametro '{0}' deve avere un valore non Null quando viene terminato perché il parametro '{1}' è non Null. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index f08227b5ad218..d7ffc804b7376 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -1207,6 +1207,11 @@ ref 代入の左辺は、ref ローカルまたはパラメーターにする必要があります。 + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. リレーショナル パターンは、浮動小数点の NaN に使用することはできません。 @@ -1822,6 +1827,16 @@ Null 許容型は null チェックされており、null の場合はスローされます。 + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. パラメーター '{1}' が null 以外であるため、パラメーター '{0}' には、終了時に null 以外の値が含まれている必要があります。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index f14edbed323cf..df5f883c32b1e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -1207,6 +1207,11 @@ 참조 할당의 왼쪽은 참조 로컬 또는 매개 변수여야 합니다. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. 부동 소수점 NaN에는 관계형 패턴을 사용할 수 없습니다. @@ -1822,6 +1827,16 @@ nullable 형식은 Null로 확인되며 Null이면 throw됩니다. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. 매개 변수 '{1}'이(가) null이 아니므로 매개 변수 '{0}'은(는) 종료할 때 null이 아닌 값을 가져야 합니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 0536e8a94722b..328b46dd83543 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -1207,6 +1207,11 @@ Lewa strona przypisania odwołania musi być odwołaniem lokalnym lub parametrem. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Wzorców relacyjnych nie można używać na potrzeby zmiennoprzecinkowej wartości NaN. @@ -1822,6 +1827,16 @@ Typ dopuszczający wartość null jest sprawdzony przy użyciu wartości null i będzie widoczny w przypadku wartości null. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. Parametr „{0}” musi mieć wartość inną niż null podczas kończenia działania, ponieważ parametr „{1}” ma wartość inną niż null. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 90eaa5624ee2a..40d44160e793a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -1207,6 +1207,11 @@ O lado esquerdo da atribuição ref precisa ser um parâmetro ou local ref. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Os padrões relacionais não podem ser usados para um NaN de ponto flutuante. @@ -1822,6 +1827,16 @@ O tipo anulável é verificado como nulo e será lançado se for nulo. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. O parâmetro '{0}' precisa ter um valor não nulo durante a saída porque o parâmetro '{1}' não é nulo. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 59d56531c7bda..b604a5ff09381 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -1207,6 +1207,11 @@ Левая часть выражения назначения ссылки должна быть локальной ссылкой или параметром. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. Реляционные шаблоны не могут использоваться для NaN с плавающей запятой. @@ -1822,6 +1827,16 @@ Для типа, допускающего значение NULL, выполнена проверка значения NULL. Он будет выдаваться, если ему присвоено значение NULL. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. При выходе параметр "{0}" должен иметь значение, отличное от NULL, так как параметр "{1}" имеет значение, отличное от NULL. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 67c005075a5bf..58d282a6171f8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -1207,6 +1207,11 @@ ref atamasının sol tarafı, yerel ref veya parametresi olmalıdır. + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. İlişkisel desenler, kayan noktalı NaN için kullanılamaz. @@ -1822,6 +1827,16 @@ Boş değer atanabilir tip null denetimlidir ve null ise atılır. + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. '{1}' parametresi null olmadığından '{0}' parametresi çıkış yaparken null olmayan bir değere sahip olmalıdır. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 16ec3b986d101..0a7543bfb358b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -1207,6 +1207,11 @@ ref 赋值左侧必须为 ref 本地函数或参数。 + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. 关系模式可能不能用于浮点 NaN。 @@ -1822,6 +1827,16 @@ 对可以为 null 的类型进行了 null 检查,如果为 null,将抛出异常。 + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. 退出时参数“{0}”必须具有非 null 值,因为参数“{1}”是非 null。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 2f8aa17dc5122..01020f0f4fccb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -1207,6 +1207,11 @@ 參考指派的左側必須為參考本機或參數。 + + Ref returning properties cannot be required. + Ref returning properties cannot be required. + + Relational patterns may not be used for a floating-point NaN. 浮點 NaN 不可使用關聯性模式。 @@ -1822,6 +1827,16 @@ 可為 Null 的類型會檢查是否為 Null,若為 Null,則會擲回。 + + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + Required member '{0}' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + + + + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + Members attributed with 'ObsoleteAttribute' should not be required unless the containing type is obsolete or all constructors are obsolete. + + Parameter '{0}' must have a non-null value when exiting because parameter '{1}' is non-null. 因為參數 '{1}' 不是 null,所以參數 '{0}' 在結束時必須具有非 Null 值。 diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs index 7ddb94dca75a5..f70fdac7f2d69 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs @@ -1242,63 +1242,186 @@ public void RefReturningProperties() class C { private int i; - public required ref int Prop => ref i; + public required ref int Prop1 => ref i; + public required ref readonly int Prop2 => ref i; } "); comp.VerifyDiagnostics( - // (5,29): error CS9505: Required member 'C.Prop' must be settable. - // public required ref int Prop => ref i; - Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Prop").WithArguments("C.Prop").WithLocation(5, 29) + // (5,29): error CS9505: Required member 'C.Prop1' must be settable. + // public required ref int Prop1 => ref i; + Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Prop1").WithArguments("C.Prop1").WithLocation(5, 29), + // (5,29): error CS9514: Ref returning properties cannot be required. + // public required ref int Prop1 => ref i; + Diagnostic(ErrorCode.ERR_RefReturningPropertiesCannotBeRequired, "Prop1").WithLocation(5, 29), + // (6,38): error CS9505: Required member 'C.Prop2' must be settable. + // public required ref readonly int Prop2 => ref i; + Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Prop2").WithArguments("C.Prop2").WithLocation(6, 38), + // (6,38): error CS9514: Ref returning properties cannot be required. + // public required ref readonly int Prop2 => ref i; + Diagnostic(ErrorCode.ERR_RefReturningPropertiesCannotBeRequired, "Prop2").WithLocation(6, 38) ); } - [Fact] - public void UnsettableMembers() - { - var comp = CreateCompilationWithRequiredMembers(@" + [Theory] + [InlineData("internal")] + [InlineData("internal protected")] + [InlineData("protected")] + [InlineData("private protected")] + [InlineData("private")] + public void UnsettableMembers(string setterAccessibility) + { + var comp = CreateCompilationWithRequiredMembers($$""" #pragma warning disable CS0649 // Unassigned field -class C +public class C { public required readonly int Field; public required int Prop1 { get; } - public required int Prop2 { get; protected set; } + public required int Prop2 { get; {{setterAccessibility}} set; } } -"); +"""); comp.VerifyDiagnostics( - // (5,34): error CS9505: Required member 'C.Field' must be settable. + // (4,34): error CS9505: Required member 'C.Field' must be settable. // public required readonly int Field; - Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Field").WithArguments("C.Field").WithLocation(5, 34), - // (6,25): error CS9505: Required member 'C.Prop1' must be settable. + Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Field").WithArguments("C.Field").WithLocation(4, 34), + // (5,25): error CS9505: Required member 'C.Prop1' must be settable. // public required int Prop1 { get; } - Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Prop1").WithArguments("C.Prop1").WithLocation(6, 25), - // PROTOTYPE(req): Better error message? - // (7,25): error CS9503: Required member 'C.Prop2' cannot be less visible or have a setter less visible than the containing type 'C'. - // public required int Prop2 { get; protected set; } - Diagnostic(ErrorCode.ERR_RequiredMemberCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("C.Prop2", "C").WithLocation(7, 25) + Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSettable, "Prop1").WithArguments("C.Prop1").WithLocation(5, 25), + // (6,25): error CS9503: Required member 'C.Prop2' cannot be less visible or have a setter less visible than the containing type 'C'. + // public required int Prop2 { get; private set; } + Diagnostic(ErrorCode.ERR_RequiredMemberCannotBeLessVisibleThanContainingType, "Prop2").WithArguments("C.Prop2", "C").WithLocation(6, 25) ); } [Fact] - public void ObsoleteMember() + public void ObsoleteMember_NoObsoleteContext() { - var comp = CreateCompilationWithRequiredMembers(@" -using System; -#pragma warning disable CS0649 // Unassigned field -class C -{ - [Obsolete] - public required int Field; - [Obsolete] - public required int Prop1 { get; set; } -} -"); + var comp = CreateCompilationWithRequiredMembers(""" + using System; + #pragma warning disable CS0649 // Unassigned field + class C + { + [Obsolete] + public required int Field; + [Obsolete] + public required int Prop1 { get; set; } + } + """); + + comp.VerifyDiagnostics( + // (6,25): warning CS9513: Required member 'C.Field' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Field; + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Field").WithArguments("C.Field").WithLocation(6, 25), + // (8,25): warning CS9513: Required member 'C.Prop1' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Prop1 { get; set; } + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Prop1").WithArguments("C.Prop1").WithLocation(8, 25) + ); + } + + [Fact] + public void ObsoleteMember_NoObsoleteContext_Struct() + { + var comp = CreateCompilationWithRequiredMembers(""" + using System; + #pragma warning disable CS0649 // Unassigned field + struct S + { + [Obsolete] + public required int Field; + [Obsolete] + public required int Prop1 { get; set; } + } + """); + + comp.VerifyDiagnostics( + // (6,25): warning CS9513: Required member 'S.Field' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Field; + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Field").WithArguments("S.Field").WithLocation(6, 25), + // (8,25): warning CS9513: Required member 'S.Prop1' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Prop1 { get; set; } + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Prop1").WithArguments("S.Prop1").WithLocation(8, 25) + ); + } + + [Fact] + public void ObsoleteMember_ObsoleteContext() + { + var comp = CreateCompilationWithRequiredMembers(""" + using System; + #pragma warning disable CS0649 // Unassigned field + [Obsolete] + class C + { + [Obsolete] + public required int Field; + [Obsolete] + public required int Prop1 { get; set; } + } + """); + + comp.VerifyDiagnostics(); + } + + [Fact] + public void ObsoleteMember_ObsoleteOrSetsRequiredMembersConstructors_01() + { + var comp = CreateCompilationWithRequiredMembers(""" + using System; + using System.Diagnostics.CodeAnalysis; + #pragma warning disable CS0649 // Unassigned field + class C + { + [Obsolete] + public C() { } + [SetsRequiredMembers] + public C(int i) { } + + [Obsolete] + public required int Field; + [Obsolete] + public required int Prop1 { get; set; } + } + + """); - // PROTOTYPE(req): Confirm with LDM whether we want a warning here. comp.VerifyDiagnostics(); } + [Fact] + public void ObsoleteMember_ObsoleteOrSetsRequiredMembersConstructors_02() + { + var comp = CreateCompilationWithRequiredMembers(""" + using System; + using System.Diagnostics.CodeAnalysis; + #pragma warning disable CS0649 // Unassigned field + class C + { + [Obsolete] + public C() { } + [SetsRequiredMembers] + public C(int i) { } + + public C(bool b) { } + + [Obsolete] + public required int Field; + [Obsolete] + public required int Prop1 { get; set; } + } + + """); + + comp.VerifyDiagnostics( + // (14,25): warning CS9513: Required member 'C.Field' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Field; + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Field").WithArguments("C.Field").WithLocation(14, 25), + // (16,25): warning CS9513: Required member 'C.Prop1' should not be attributed with 'ObsoleteAttribute' unless the containing type is obsolete or all constructors are obsolete. + // public required int Prop1 { get; set; } + Diagnostic(ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired, "Prop1").WithArguments("C.Prop1").WithLocation(16, 25) + ); + } + [Fact] public void ReadonlyPropertiesAndStructs() { @@ -3668,7 +3791,7 @@ public class Base public string Prop2 { get; set; } = null!; [SetsRequiredMembers] - protected Base() {} + protected Base() {} // 1 } public class Derived : Base @@ -3676,26 +3799,29 @@ public class Derived : Base public required string Prop3 { get; set; } public string Prop4 { get; set; } - public Derived() : base() + public Derived() : base() // 2 { Prop1.ToString(); Prop2.ToString(); - Prop3.ToString(); // 1 - Prop4.ToString(); // 2 + Prop3.ToString(); // 3 + Prop4.ToString(); // 4 } } """; var comp = CreateCompilationWithRequiredMembers(code); comp.VerifyDiagnostics( + // (9,15): warning CS8618: Non-nullable property 'Prop1' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. + // protected Base() {} // 1 + Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Base").WithArguments("property", "Prop1").WithLocation(9, 15), // (17,24): error CS9510: This constructor must add 'SetsRequiredMembers' because it chains to a constructor that has that attribute. - // public Derived() : base() + // public Derived() : base() // 2 Diagnostic(ErrorCode.ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers, "base").WithLocation(17, 24), // (21,9): warning CS8602: Dereference of a possibly null reference. - // Prop3.ToString(); // 1 + // Prop3.ToString(); // 3 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop3").WithLocation(21, 9), // (22,9): warning CS8602: Dereference of a possibly null reference. - // Prop4.ToString(); // 2 + // Prop4.ToString(); // 4 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop4").WithLocation(22, 9) ); } @@ -3737,6 +3863,9 @@ public Derived() : this(0) var comp = CreateCompilationWithRequiredMembers(code); comp.VerifyDiagnostics( + // (17,12): warning CS8618: Non-nullable property 'Prop3' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. + // public Derived(int unused) : base() + Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Derived").WithArguments("property", "Prop3").WithLocation(17, 12), // (22,24): error CS9510: This constructor must add 'SetsRequiredMembers' because it chains to a constructor that has that attribute. // public Derived() : this(0) Diagnostic(ErrorCode.ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers, "this").WithLocation(22, 24) diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index cc92c05f00e5a..c2f329a272eb1 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -272,6 +272,7 @@ public void WarningLevel_2() case ErrorCode.WRN_CallerArgumentExpressionAttributeSelfReferential: case ErrorCode.WRN_NullCheckedHasDefaultNull: case ErrorCode.WRN_NullCheckingOnNullableType: + case ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired: Assert.Equal(1, ErrorFacts.GetWarningLevel(errorCode)); break; case ErrorCode.WRN_MainIgnored: diff --git a/src/Compilers/VisualBasic/Portable/Symbols/ObsoleteAttributeHelpers.vb b/src/Compilers/VisualBasic/Portable/Symbols/ObsoleteAttributeHelpers.vb index c3a29d918b151..12411f11b7d10 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/ObsoleteAttributeHelpers.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/ObsoleteAttributeHelpers.vb @@ -33,7 +33,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Friend Shared Function GetObsoleteDataFromMetadata(token As EntityHandle, containingModule As PEModuleSymbol) As ObsoleteAttributeData Dim obsoleteAttributeData As ObsoleteAttributeData = Nothing ' ignoreByRefLikeMarker := False, since VB does not support ref-like types - ' PROTOTYPE(req): Determine what support will be added for VB + ' https://github.com/dotnet/roslyn/issues/61435: Determine what support will be added for VB obsoleteAttributeData = containingModule.Module.TryGetDeprecatedOrExperimentalOrObsoleteAttribute(token, New MetadataDecoder(containingModule), ignoreByRefLikeMarker:=False, ignoreRequiredMemberMarker:=False) Debug.Assert(obsoleteAttributeData Is Nothing OrElse Not obsoleteAttributeData.IsUninitialized) Return obsoleteAttributeData