Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -715,6 +715,7 @@ public readonly partial struct EventDefinition
public System.Reflection.Metadata.EntityHandle Type { get { throw null; } }
public System.Reflection.Metadata.EventAccessors GetAccessors() { throw null; }
public System.Reflection.Metadata.CustomAttributeHandleCollection GetCustomAttributes() { throw null; }
public System.Reflection.Metadata.TypeDefinitionHandle GetDeclaringType() { throw null; }
}
public readonly partial struct EventDefinitionHandle : System.IEquatable<System.Reflection.Metadata.EventDefinitionHandle>
{
Expand Down Expand Up @@ -2135,6 +2136,7 @@ public readonly partial struct PropertyDefinition
public System.Reflection.Metadata.MethodSignature<TType> DecodeSignature<TType, TGenericContext>(System.Reflection.Metadata.ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext) { throw null; }
public System.Reflection.Metadata.PropertyAccessors GetAccessors() { throw null; }
public System.Reflection.Metadata.CustomAttributeHandleCollection GetCustomAttributes() { throw null; }
public System.Reflection.Metadata.TypeDefinitionHandle GetDeclaringType() { throw null; }
public System.Reflection.Metadata.ConstantHandle GetDefaultValue() { throw null; }
}
public readonly partial struct PropertyDefinitionHandle : System.IEquatable<System.Reflection.Metadata.PropertyDefinitionHandle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,47 @@ internal int GetEventListStartFor(int rowId)
int rowOffset = (rowId - 1) * this.RowSize;
return this.Block.PeekReference(rowOffset + _EventListOffset, _IsEventRefSizeSmall);
}

internal TypeDefinitionHandle FindTypeContainingEvent(int eventRowId, int numberOfEvents)
{
int numOfRows = this.NumberOfRows;
int slot = this.Block.BinarySearchForSlot(numOfRows, this.RowSize, _EventListOffset, (uint)eventRowId, _IsEventRefSizeSmall);
int row = slot + 1;
if (row == 0)
{
return default(TypeDefinitionHandle);
}

if (row > numOfRows)
{
if (eventRowId <= numberOfEvents)
{
return GetParentType(numOfRows);
}

return default(TypeDefinitionHandle);
}

int value = this.GetEventListStartFor(row);
if (value == eventRowId)
{
while (row < numOfRows)
{
int newRow = row + 1;
value = this.GetEventListStartFor(newRow);
if (value == eventRowId)
{
row = newRow;
}
else
{
break;
}
}
}

return GetParentType(row);
}
}

internal readonly struct EventPtrTableReader
Expand Down Expand Up @@ -1343,6 +1384,47 @@ internal int GetPropertyListStartFor(int rowId)
int rowOffset = (rowId - 1) * this.RowSize;
return this.Block.PeekReference(rowOffset + _PropertyListOffset, _IsPropertyRefSizeSmall);
}

internal TypeDefinitionHandle FindTypeContainingProperty(int propertyRowId, int numberOfProperties)
{
int numOfRows = this.NumberOfRows;
int slot = this.Block.BinarySearchForSlot(numOfRows, this.RowSize, _PropertyListOffset, (uint)propertyRowId, _IsPropertyRefSizeSmall);
int row = slot + 1;
if (row == 0)
{
return default(TypeDefinitionHandle);
}

if (row > numOfRows)
{
if (propertyRowId <= numberOfProperties)
{
return GetParentType(numOfRows);
}

return default(TypeDefinitionHandle);
}

int value = this.GetPropertyListStartFor(row);
if (value == propertyRowId)
{
while (row < numOfRows)
{
int newRow = row + 1;
value = this.GetPropertyListStartFor(newRow);
if (value == propertyRowId)
{
row = newRow;
}
else
{
break;
}
}
}

return GetParentType(row);
}
}

internal readonly struct PropertyPtrTableReader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,26 @@ internal TypeDefinitionHandle GetDeclaringType(FieldDefinitionHandle fieldDef)
return TypeDefTable.FindTypeContainingField(fieldRowId, FieldTable.NumberOfRows);
}

internal TypeDefinitionHandle GetDeclaringType(EventDefinitionHandle eventDef)
{
if (UseEventPtrTable)
{
eventDef = EventPtrTable.GetEventFor(eventDef.RowId);
}

return EventMapTable.FindTypeContainingEvent(eventDef.RowId, EventTable.NumberOfRows);
}

internal TypeDefinitionHandle GetDeclaringType(PropertyDefinitionHandle propertyDef)
{
if (UsePropertyPtrTable)
{
propertyDef = PropertyPtrTable.GetPropertyFor(propertyDef.RowId);
}

return PropertyMapTable.FindTypeContainingProperty(propertyDef.RowId, PropertyTable.NumberOfRows);
}

public string GetString(DocumentNameBlobHandle handle)
{
return BlobHeap.GetDocumentName(handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ public CustomAttributeHandleCollection GetCustomAttributes()
return new CustomAttributeHandleCollection(_reader, Handle);
}

/// <summary>
/// Returns a handle to the type that declares this event.
/// </summary>
public TypeDefinitionHandle GetDeclaringType()
{
return _reader.GetDeclaringType(Handle);
}

public EventAccessors GetAccessors()
{
int adder = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public TType DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TTyp
return decoder.DecodeFieldSignature(ref blob);
}

/// <summary>
/// Returns a handle to the type that declares this field.
/// </summary>
public TypeDefinitionHandle GetDeclaringType()
{
return _reader.GetDeclaringType(Handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ public MethodImplAttributes ImplAttributes
}
}

/// <summary>
/// Returns a handle to the type that declares this method.
/// </summary>
public TypeDefinitionHandle GetDeclaringType()
{
return _reader.GetDeclaringType(Handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ public CustomAttributeHandleCollection GetCustomAttributes()
return new CustomAttributeHandleCollection(_reader, Handle);
}

/// <summary>
/// Returns a handle to the type that declares this property.
/// </summary>
public TypeDefinitionHandle GetDeclaringType()
{
return _reader.GetDeclaringType(Handle);
}

public PropertyAccessors GetAccessors()
{
int getter = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,41 @@ public void ValidateTypeDefinitionIsNestedWindowsProjection()
Assert.Equal(typeDef.Attributes.IsNested(), typeDef.IsNested);
}
}

[Fact]
public void ValidateDeclaringType()
{
var reader = MetadataReaderTests.GetMetadataReader(Misc.Members);

foreach (var typeDefHandle in reader.TypeDefinitions)
{
var typeDef = reader.GetTypeDefinition(typeDefHandle);
foreach (var nestedTypeHandle in typeDef.GetNestedTypes())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a sanity check here to make sure that these foreach statement actually loop through at least one? Like:

Assert.True(typeDef.GetNestedTypes().Length > 0);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test assembly actually dosen't have any nested types. I tried to add some but after recompiling it this assert failed.

Your suggested assert wouldn't currently work, because not all types have all kinds of members each.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added asserts that GetTypesWithEvents() and GetTypesWithProperties() are not empty, and commented out the asserts on the nested classes.

{
var nestedType = reader.GetTypeDefinition(nestedTypeHandle);
Assert.Equal(typeDefHandle, nestedType.GetDeclaringType());
}
foreach (var fieldHandle in typeDef.GetFields())
{
var field = reader.GetFieldDefinition(fieldHandle);
Assert.Equal(typeDefHandle, field.GetDeclaringType());
}
foreach (var methodHandle in typeDef.GetMethods())
{
var method = reader.GetMethodDefinition(methodHandle);
Assert.Equal(typeDefHandle, method.GetDeclaringType());
}
foreach (var eventHandle in typeDef.GetEvents())
{
var eventDef = reader.GetEventDefinition(eventHandle);
Assert.Equal(typeDefHandle, eventDef.GetDeclaringType());
}
foreach (var propertyHandle in typeDef.GetProperties())
{
var property = reader.GetPropertyDefinition(propertyHandle);
Assert.Equal(typeDefHandle, property.GetDeclaringType());
}
}
}
}
}