Skip to content

Commit adb41f8

Browse files
committed
Fixed some inherited record types being incorrectly identified as class types
1 parent 126e870 commit adb41f8

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,8 @@ private bool ComputeIsRecord()
816816
var metadata = module.metadata;
817817
var typeDef = metadata.GetTypeDefinition(handle);
818818

819+
bool isRecord = false;
820+
819821
bool getEqualityContract = isStruct;
820822
bool toString = false;
821823
bool printMembers = false;
@@ -824,25 +826,46 @@ private bool ComputeIsRecord()
824826
bool opEquality = false;
825827
bool opInequality = false;
826828
bool clone = isStruct;
827-
foreach (var methodHandle in typeDef.GetMethods())
829+
830+
// Consider inherited properties as well: check for an EqualityContract property.
831+
foreach (var prop in this.GetProperties())
828832
{
829-
var method = metadata.GetMethodDefinition(methodHandle);
830-
if (metadata.StringComparer.Equals(method.Name, "Clone"))
833+
if (prop.Name == "EqualityContract" && prop.Getter != null)
834+
{
835+
getEqualityContract = true;
836+
break;
837+
}
838+
}
839+
840+
// Consider inherited members as well: use GetMethods() which includes inherited methods
841+
// via the GetMembersHelper. This ensures methods like ToString/PrintMembers from
842+
// base types satisfy the record shape requirements.
843+
foreach (var m in this.GetMethods())
844+
{
845+
string name = m.Name;
846+
// error CS8859: Members named 'Clone' are disallowed in records.
847+
if (name == "Clone")
831848
{
832-
// error CS8859: Members named 'Clone' are disallowed in records.
833849
return false;
834850
}
835851

836-
getEqualityContract |= metadata.StringComparer.Equals(method.Name, "get_EqualityContract");
837-
toString |= metadata.StringComparer.Equals(method.Name, "ToString");
838-
printMembers |= metadata.StringComparer.Equals(method.Name, "PrintMembers");
839-
getHashCode |= metadata.StringComparer.Equals(method.Name, "GetHashCode");
840-
equals |= metadata.StringComparer.Equals(method.Name, "Equals");
841-
opEquality |= metadata.StringComparer.Equals(method.Name, "op_Equality");
842-
opInequality |= metadata.StringComparer.Equals(method.Name, "op_Inequality");
843-
clone |= metadata.StringComparer.Equals(method.Name, "<Clone>$");
852+
// Also accept a getter method named get_EqualityContract
853+
getEqualityContract |= (name == "get_EqualityContract");
854+
toString |= (name == "ToString");
855+
printMembers |= (name == "PrintMembers");
856+
getHashCode |= (name == "GetHashCode");
857+
equals |= (name == "Equals");
858+
opEquality |= (name == "op_Equality");
859+
opInequality |= (name == "op_Inequality");
860+
clone |= (name == "<Clone>$");
861+
862+
isRecord = getEqualityContract & toString & printMembers & getHashCode & equals & opEquality & opInequality & clone;
863+
if (isRecord)
864+
{
865+
break;
866+
}
844867
}
845-
return getEqualityContract & toString & printMembers & getHashCode & equals & opEquality & opInequality & clone;
868+
return isRecord;
846869
}
847870
#endregion
848871
}

0 commit comments

Comments
 (0)