Skip to content

Commit

Permalink
Synthesize equality operators for records. (#46497)
Browse files Browse the repository at this point in the history
Closes #46381.
  • Loading branch information
AlekseyTs authored Aug 4, 2020
1 parent e93d356 commit 932828f
Show file tree
Hide file tree
Showing 13 changed files with 789 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ internal override IOperation GetOperationWorker(CSharpSyntaxNode node, Cancellat
case AccessorDeclarationSyntax accessor:
model = (accessor.Body != null || accessor.ExpressionBody != null) ? GetOrAddModel(node) : null;
break;
case RecordDeclarationSyntax { ParameterList: { }, PrimaryConstructorBaseType: { } } recordDeclaration when TryGetSynthesizedRecordConstructor(recordDeclaration) is SynthesizedRecordConstructor ctor:
case RecordDeclarationSyntax { ParameterList: { }, PrimaryConstructorBaseType: { } } recordDeclaration when TryGetSynthesizedRecordConstructor(recordDeclaration) is SynthesizedRecordConstructor:
model = GetOrAddModel(recordDeclaration);
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,13 @@ private void CheckForEqualityAndGetHashCode(DiagnosticBag diagnostics)
return;
}

if (IsRecord)
{
// For records the warnings reported below are simply going to echo record specific errors,
// producing more noise.
return;
}

bool hasOp = this.GetOperators(WellKnownMemberNames.EqualityOperatorName).Any() ||
this.GetOperators(WellKnownMemberNames.InequalityOperatorName).Any();
bool overridesEquals = this.TypeOverridesObjectMethod("Equals");
Expand Down Expand Up @@ -3029,6 +3036,7 @@ private void AddSynthesizedRecordMembersIfNecessary(MembersAndInitializersBuilde
addOtherEquals();
addObjectEquals(thisEquals);
addHashCode(equalityContract);
addEqualityOperators();

memberSignatures.Free();

Expand Down Expand Up @@ -3361,6 +3369,12 @@ void addOtherEquals()
members.Add(new SynthesizedRecordBaseEquals(this, memberOffset: members.Count, diagnostics));
}
}

void addEqualityOperators()
{
members.Add(new SynthesizedRecordEqualityOperator(this, memberOffset: members.Count, diagnostics));
members.Add(new SynthesizedRecordInequalityOperator(this, memberOffset: members.Count, diagnostics));
}
}

private void AddSynthesizedConstructorsIfNecessary(ArrayBuilder<Symbol> members, ArrayBuilder<ArrayBuilder<FieldOrPropertyInitializer.Builder>> staticInitializers, DiagnosticBag diagnostics)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ public override ImmutableArray<Location> Locations
}
}

internal override int ParameterCount
internal sealed override int ParameterCount
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
Expand Down Expand Up @@ -43,6 +45,10 @@ private SourceUserDefinedConversionSymbol(
containingType,
location,
syntax,
MakeDeclarationModifiers(syntax, location, diagnostics),
hasBody: syntax.HasAnyBody(),
isExpressionBodied: syntax.Body == null && syntax.ExpressionBody != null,
isIterator: SyntaxFacts.HasYieldOperations(syntax.Body),
diagnostics)
{
CheckForBlockAndExpressionBody(
Expand All @@ -54,31 +60,39 @@ private SourceUserDefinedConversionSymbol(
}
}

internal new ConversionOperatorDeclarationSyntax GetSyntax()
internal ConversionOperatorDeclarationSyntax GetSyntax()
{
Debug.Assert(syntaxReferenceOpt != null);
return (ConversionOperatorDeclarationSyntax)syntaxReferenceOpt.GetSyntax();
}

protected override ParameterListSyntax ParameterListSyntax
protected override int GetParameterCountFromSyntax()
{
get
{
return GetSyntax().ParameterList;
}
return GetSyntax().ParameterList.ParameterCount;
}

protected override TypeSyntax ReturnTypeSyntax
protected override Location ReturnTypeLocation
{
get
{
return GetSyntax().Type;
return GetSyntax().Type.Location;
}
}

internal override bool GenerateDebugInfo
{
get { return true; }
}

internal sealed override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations()
{
return OneOrMany.Create(this.GetSyntax().AttributeLists);
}

protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymbol> Parameters) MakeParametersAndBindReturnType(DiagnosticBag diagnostics)
{
ConversionOperatorDeclarationSyntax declarationSyntax = GetSyntax();
return MakeParametersAndBindReturnType(declarationSyntax, declarationSyntax.Type, diagnostics);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
Expand All @@ -20,8 +22,7 @@ public static SourceUserDefinedOperatorSymbol CreateUserDefinedOperatorSymbol(
string name = OperatorFacts.OperatorNameFromDeclaration(syntax);

return new SourceUserDefinedOperatorSymbol(
containingType, name, location, syntax, diagnostics,
syntax.Body == null && syntax.ExpressionBody != null);
containingType, name, location, syntax, diagnostics);
}

// NOTE: no need to call WithUnsafeRegionIfNecessary, since the signature
Expand All @@ -32,14 +33,17 @@ private SourceUserDefinedOperatorSymbol(
string name,
Location location,
OperatorDeclarationSyntax syntax,
DiagnosticBag diagnostics,
bool isExpressionBodied) :
DiagnosticBag diagnostics) :
base(
MethodKind.UserDefinedOperator,
name,
containingType,
location,
syntax,
MakeDeclarationModifiers(syntax, location, diagnostics),
hasBody: syntax.HasAnyBody(),
isExpressionBodied: syntax.Body == null && syntax.ExpressionBody != null,
isIterator: SyntaxFacts.HasYieldOperations(syntax.Body),
diagnostics)
{
CheckForBlockAndExpressionBody(
Expand All @@ -51,31 +55,39 @@ private SourceUserDefinedOperatorSymbol(
}
}

internal new OperatorDeclarationSyntax GetSyntax()
internal OperatorDeclarationSyntax GetSyntax()
{
Debug.Assert(syntaxReferenceOpt != null);
return (OperatorDeclarationSyntax)syntaxReferenceOpt.GetSyntax();
}

protected override ParameterListSyntax ParameterListSyntax
protected override int GetParameterCountFromSyntax()
{
get
{
return GetSyntax().ParameterList;
}
return GetSyntax().ParameterList.ParameterCount;
}

protected override TypeSyntax ReturnTypeSyntax
protected override Location ReturnTypeLocation
{
get
{
return GetSyntax().ReturnType;
return GetSyntax().ReturnType.Location;
}
}

internal override bool GenerateDebugInfo
{
get { return true; }
}

internal sealed override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations()
{
return OneOrMany.Create(this.GetSyntax().AttributeLists);
}

protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymbol> Parameters) MakeParametersAndBindReturnType(DiagnosticBag diagnostics)
{
OperatorDeclarationSyntax declarationSyntax = GetSyntax();
return MakeParametersAndBindReturnType(declarationSyntax, declarationSyntax.ReturnType, diagnostics);
}
}
}
Loading

0 comments on commit 932828f

Please sign in to comment.