Skip to content
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

Synthesize equality operators for records. #46497

Merged
merged 4 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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