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

[release/9.0-rc1] Fix Type System Equivalence Checks #106666

Closed
Closed
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 @@ -14,6 +14,7 @@ public partial class EcmaType
private TypeIdentifierData ComputeTypeIdentifierFromGuids()
{
CustomAttributeValue<TypeDesc>? guidAttribute;

if (IsInterface && _typeDefinition.Attributes.HasFlag(TypeAttributes.Import))
{
// ComImport interfaces get scope from their GUID
Expand All @@ -23,6 +24,7 @@ private TypeIdentifierData ComputeTypeIdentifierFromGuids()
{
// other equivalent types get it from the declaring assembly
var attributeHandle = this.MetadataReader.GetCustomAttributeHandle(MetadataReader.GetAssemblyDefinition().GetCustomAttributes(), "System.Runtime.InteropServices", "GuidAttribute");

if (attributeHandle.IsNil)
return null;

Expand All @@ -40,6 +42,7 @@ private TypeIdentifierData ComputeTypeIdentifierFromGuids()

string scope = (string)guidAttribute.Value.FixedArguments[0].Value;
string name = this.Name;

if (this.Namespace != null)
name = this.Namespace + "." + name;

Expand All @@ -53,6 +56,7 @@ private TypeIdentifierData ComputeTypeIdentifierData()

// Check for type identifier attribute
var typeIdentifierAttribute = this.GetDecodedCustomAttribute("System.Runtime.InteropServices", "TypeIdentifierAttribute");

if (typeIdentifierAttribute.HasValue)
{
// If the type has a type identifier attribute it is always considered to be type equivalent
Expand All @@ -68,28 +72,38 @@ private TypeIdentifierData ComputeTypeIdentifierData()
if (typeIdentifierAttribute.Value.FixedArguments[1].Type != Context.GetWellKnownType(WellKnownType.String))
return null;

_data = new TypeIdentifierData((string)typeIdentifierAttribute.Value.FixedArguments[0].Value, (string)typeIdentifierAttribute.Value.FixedArguments[1].Value);
return _data;
return new TypeIdentifierData((string)typeIdentifierAttribute.Value.FixedArguments[0].Value, (string)typeIdentifierAttribute.Value.FixedArguments[1].Value);
}
else

// In addition to the TypeIdentifierAttribute certain other types may also be opted in to type equivalence
if (Context.SupportsCOMInterop)
{
// In addition to the TypeIdentifierAttribute certain other types may also be opted in to type equivalence
if (Context.SupportsCOMInterop)
// 1. The assembly is marked with ImportedFromTypeLibAttribute or PrimaryInteropAssemblyAttribute
// We will verify this by checking for their attribute handles using the Metadata Reader.

CustomAttributeHandle importedFromTypeLibHdl = this.MetadataReader.GetCustomAttributeHandle(
MetadataReader.GetAssemblyDefinition().GetCustomAttributes(),
"System.Runtime.InteropServices",
"ImportedFromTypeLibAttribute"
);

CustomAttributeHandle primaryInteropAssemblyHdl = this.MetadataReader.GetCustomAttributeHandle(
MetadataReader.GetAssemblyDefinition().GetCustomAttributes(),
"System.Runtime.InteropServices",
"PrimaryInteropAssemblyAttribute"
);

if (!importedFromTypeLibHdl.IsNil || !primaryInteropAssemblyHdl.IsNil)
{
// 1. Type is within assembly marked with ImportedFromTypeLibAttribute or PrimaryInteropAssemblyAttribute
if (this.HasCustomAttribute("System.Runtime.InteropServices", "ImportedFromTypeLibAttribute") || this.HasCustomAttribute("System.Runtime.InteropServices", "PrimaryInteropAssemblyAttribute"))
{
// This type has a TypeIdentifier attribute if it has an appropriate shape to be considered type equivalent
}

// This type has a TypeIdentifier attribute if it has an appropriate shape to be considered type equivalent
if (!TypeHasCharacteristicsRequiredToBeTypeEquivalent)
return null;

_data = ComputeTypeIdentifierFromGuids();
return ComputeTypeIdentifierFromGuids();
}

return null;
}

return null;
}

public override TypeIdentifierData TypeIdentifierData
Expand Down
Loading