-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Align addition of a synthesized override of Base.Equals(Base? other) in records with the latest design. #45601
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#nullable enable | ||
|
||
using System.Collections.Immutable; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
|
||
namespace Microsoft.CodeAnalysis.CSharp.Symbols | ||
{ | ||
/// <summary> | ||
/// If the record type is derived from a base record type Base, the record type includes | ||
/// a synthesized override of the strongly-typed Equals(Base other). The synthesized | ||
/// override is sealed. It is an error if the override is declared explicitly. | ||
/// The synthesized override returns Equals((object?)other). | ||
/// </summary> | ||
internal sealed class SynthesizedRecordBaseEquals : SynthesizedRecordOrdinaryMethod | ||
{ | ||
public SynthesizedRecordBaseEquals(SourceMemberContainerTypeSymbol containingType, int memberOffset, DiagnosticBag diagnostics) | ||
: base(containingType, WellKnownMemberNames.ObjectEquals, memberOffset, diagnostics) | ||
{ | ||
} | ||
|
||
protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModifiers allowedModifiers, DiagnosticBag diagnostics) | ||
{ | ||
const DeclarationModifiers result = DeclarationModifiers.Public | DeclarationModifiers.Override | DeclarationModifiers.Sealed; | ||
Debug.Assert((result & ~allowedModifiers) == 0); | ||
return result; | ||
} | ||
|
||
protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymbol> Parameters, bool IsVararg, ImmutableArray<TypeParameterConstraintClause> DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(DiagnosticBag diagnostics) | ||
{ | ||
var compilation = DeclaringCompilation; | ||
var location = ReturnTypeLocation; | ||
return (ReturnType: TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Boolean, location, diagnostics)), | ||
Parameters: ImmutableArray.Create<ParameterSymbol>( | ||
new SourceSimpleParameterSymbol(owner: this, | ||
TypeWithAnnotations.Create(ContainingType.BaseTypeNoUseSiteDiagnostics, NullableAnnotation.Annotated), | ||
ordinal: 0, RefKind.None, "", isDiscard: false, Locations)), | ||
IsVararg: false, | ||
DeclaredConstraintsForOverrideOrImplementation: ImmutableArray<TypeParameterConstraintClause>.Empty); | ||
} | ||
|
||
protected override int GetParameterCountFromSyntax() => 1; | ||
|
||
protected override void MethodChecks(DiagnosticBag diagnostics) | ||
{ | ||
base.MethodChecks(diagnostics); | ||
|
||
var overridden = OverriddenMethod; | ||
|
||
if (overridden is null) | ||
{ | ||
return; | ||
} | ||
|
||
if (overridden is object && | ||
!overridden.ContainingType.Equals(ContainingType.BaseTypeNoUseSiteDiagnostics, TypeCompareKind.AllIgnoreOptions)) | ||
{ | ||
diagnostics.Add(ErrorCode.ERR_DoesNotOverrideBaseEquals, Locations[0], this, ContainingType.BaseTypeNoUseSiteDiagnostics); | ||
} | ||
} | ||
|
||
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) | ||
{ | ||
var F = new SyntheticBoundNodeFactory(this, this.SyntaxNode, compilationState, diagnostics); | ||
|
||
try | ||
{ | ||
var retExpr = F.Call( | ||
F.This(), | ||
ContainingType.GetMembersUnordered().OfType<SynthesizedRecordObjEquals>().Single(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to lookup members by name and then filter down to SynthesizedRecordObjEquals? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The code is simpler this way and I don't think it would lead to any noticeable perf difference. In reply to: 449208838 [](ancestors = 449208838) |
||
F.Convert(F.SpecialType(SpecialType.System_Object), F.Parameter(Parameters[0]))); | ||
|
||
F.CloseMethod(F.Block(F.Return(retExpr))); | ||
} | ||
catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) | ||
{ | ||
diagnostics.Add(ex.Diagnostic); | ||
F.CloseMethod(F.ThrowNull()); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check seems redundant. #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the previous
if
can be removed.In reply to: 449207981 [](ancestors = 449207981)