| File: Symbols\Synthesized\Records\SynthesizedRecordObjEquals.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// 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. using System.Collections.Immutable; using System.Diagnostics; namespace Microsoft.CodeAnalysis.CSharp.Symbols { /// <summary> /// The record type includes a synthesized override of object.Equals(object? obj). /// It is an error if the override is declared explicitly. The synthesized override /// returns Equals(other as R) where R is the record type. /// </summary> internal sealed class SynthesizedRecordObjEquals : SynthesizedRecordObjectMethod { private readonly MethodSymbol _typedRecordEquals; public SynthesizedRecordObjEquals(SourceMemberContainerTypeSymbol containingType, MethodSymbol typedRecordEquals, int memberOffset) : base(containingType, WellKnownMemberNames.ObjectEquals, memberOffset, isReadOnly: containingType.IsRecordStruct) { _typedRecordEquals = typedRecordEquals; } protected override SpecialMember OverriddenSpecialMember => SpecialMember.System_Object__Equals; protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymbol> Parameters) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; var annotation = ContainingType.IsRecordStruct ? NullableAnnotation.Oblivious : NullableAnnotation.Annotated; return (ReturnType: TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Boolean, location, diagnostics)), Parameters: ImmutableArray.Create<ParameterSymbol>( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Object, location, diagnostics), annotation), ordinal: 0, RefKind.None, "obj", Locations))); } protected override int GetParameterCountFromSyntax() => 1; internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, this.SyntaxNode, compilationState, diagnostics); try { if (_typedRecordEquals.ReturnType.SpecialType != SpecialType.System_Boolean) { // There is a signature mismatch, an error was reported elsewhere F.CloseMethod(F.ThrowNull()); return; } var paramAccess = F.Parameter(Parameters[0]); BoundExpression expression; if (ContainingType.IsRecordStruct) { // For record structs: // return other is R && Equals((R)other) Debug.Assert(paramAccess.Type.IsObjectType()); Conversion c = F.ClassifyEmitConversion(paramAccess, ContainingType); Debug.Assert(c.IsUnboxing); expression = F.LogicalAnd( F.Is(paramAccess, ContainingType), F.Call(F.This(), _typedRecordEquals, F.Convert(ContainingType, paramAccess, c))); } else { // For record classes: // return this.Equals(param as ContainingType); expression = F.Call(F.This(), _typedRecordEquals, F.As(paramAccess, ContainingType)); } F.CloseMethod(F.Block(ImmutableArray.Create<BoundStatement>(F.Return(expression)))); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); } } } }