Browse Source

Fixed some inherited record types being incorrectly identified as class types

pull/3596/head
sonyps5201314 3 months ago
parent
commit
adb41f894b
  1. 49
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

49
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -816,6 +816,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var metadata = module.metadata; var metadata = module.metadata;
var typeDef = metadata.GetTypeDefinition(handle); var typeDef = metadata.GetTypeDefinition(handle);
bool isRecord = false;
bool getEqualityContract = isStruct; bool getEqualityContract = isStruct;
bool toString = false; bool toString = false;
bool printMembers = false; bool printMembers = false;
@ -824,25 +826,46 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool opEquality = false; bool opEquality = false;
bool opInequality = false; bool opInequality = false;
bool clone = isStruct; bool clone = isStruct;
foreach (var methodHandle in typeDef.GetMethods())
// Consider inherited properties as well: check for an EqualityContract property.
foreach (var prop in this.GetProperties())
{ {
var method = metadata.GetMethodDefinition(methodHandle); if (prop.Name == "EqualityContract" && prop.Getter != null)
if (metadata.StringComparer.Equals(method.Name, "Clone")) {
getEqualityContract = true;
break;
}
}
// Consider inherited members as well: use GetMethods() which includes inherited methods
// via the GetMembersHelper. This ensures methods like ToString/PrintMembers from
// base types satisfy the record shape requirements.
foreach (var m in this.GetMethods())
{
string name = m.Name;
// error CS8859: Members named 'Clone' are disallowed in records.
if (name == "Clone")
{ {
// error CS8859: Members named 'Clone' are disallowed in records.
return false; return false;
} }
getEqualityContract |= metadata.StringComparer.Equals(method.Name, "get_EqualityContract"); // Also accept a getter method named get_EqualityContract
toString |= metadata.StringComparer.Equals(method.Name, "ToString"); getEqualityContract |= (name == "get_EqualityContract");
printMembers |= metadata.StringComparer.Equals(method.Name, "PrintMembers"); toString |= (name == "ToString");
getHashCode |= metadata.StringComparer.Equals(method.Name, "GetHashCode"); printMembers |= (name == "PrintMembers");
equals |= metadata.StringComparer.Equals(method.Name, "Equals"); getHashCode |= (name == "GetHashCode");
opEquality |= metadata.StringComparer.Equals(method.Name, "op_Equality"); equals |= (name == "Equals");
opInequality |= metadata.StringComparer.Equals(method.Name, "op_Inequality"); opEquality |= (name == "op_Equality");
clone |= metadata.StringComparer.Equals(method.Name, "<Clone>$"); opInequality |= (name == "op_Inequality");
clone |= (name == "<Clone>$");
isRecord = getEqualityContract & toString & printMembers & getHashCode & equals & opEquality & opInequality & clone;
if (isRecord)
{
break;
}
} }
return getEqualityContract & toString & printMembers & getHashCode & equals & opEquality & opInequality & clone; return isRecord;
} }
#endregion #endregion
} }

Loading…
Cancel
Save