Skip to content

Commit

Permalink
Add IsTypeOfUtf8 as well as Utf8String versions of Name properties to…
Browse files Browse the repository at this point in the history
… avoid unnecessary string allocations during member resolution.
  • Loading branch information
Washi1337 committed Nov 27, 2022
1 parent 983873b commit baf25ac
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 13 deletions.
30 changes: 17 additions & 13 deletions src/AsmResolver.DotNet/DefaultMetadataResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ public IAssemblyResolver AssemblyResolver
return null;

var resolvedType = LookupInCache(exportedType);
if (resolvedType != null)
if (resolvedType is not null)
return resolvedType;

var resolution = new TypeResolution(AssemblyResolver);
resolvedType = resolution.ResolveExportedType(exportedType);
if (resolvedType != null)
if (resolvedType is not null)
_typeCache[exportedType] = resolvedType;

return resolvedType;
Expand Down Expand Up @@ -137,6 +137,10 @@ public IAssemblyResolver AssemblyResolver
if (declaringType is null)
return null;

var name = field is MemberReference member
? member.Name
: (Utf8String?) field.Name;

for (int i = 0; i < declaringType.Fields.Count; i++)
{
var candidate = declaringType.Fields[i];
Expand Down Expand Up @@ -171,7 +175,7 @@ public TypeResolution(IAssemblyResolver resolver)
{
case TableIndex.AssemblyRef:
var assemblyDefScope = _assemblyResolver.Resolve((AssemblyReference) scope);
return assemblyDefScope != null
return assemblyDefScope is not null
? FindTypeInAssembly(assemblyDefScope, reference.Namespace, reference.Name)
: null;

Expand All @@ -180,7 +184,7 @@ public TypeResolution(IAssemblyResolver resolver)

case TableIndex.TypeRef:
var typeDefScope = ResolveTypeReference((TypeReference) scope);
return typeDefScope != null
return typeDefScope is not null
? FindTypeInType(typeDefScope, reference.Name)
: null;

Expand All @@ -200,20 +204,20 @@ public TypeResolution(IAssemblyResolver resolver)
{
case TableIndex.AssemblyRef:
var assembly = _assemblyResolver.Resolve((AssemblyReference) implementation);
return assembly is {}
return assembly is not null
? FindTypeInAssembly(assembly, exportedType.Namespace, exportedType.Name)
: null;

case TableIndex.File when !string.IsNullOrEmpty(implementation.Name):
var module = FindModuleInAssembly(exportedType.Module!.Assembly!, implementation.Name!);
return module is {}
return module is not null
? FindTypeInModule(module, exportedType.Namespace, exportedType.Name)
: null;

case TableIndex.ExportedType:
var exportedDeclaringType = (ExportedType) implementation;
var declaringType = ResolveExportedType(exportedDeclaringType);
return declaringType is {}
return declaringType is not null
? FindTypeInType(declaringType, exportedType.Name)
: null;

Expand All @@ -228,33 +232,33 @@ public TypeResolution(IAssemblyResolver resolver)
{
var module = assembly.Modules[i];
var type = FindTypeInModule(module, ns, name);
if (type != null)
if (type is not null)
return type;
}

return null;
}

private TypeDefinition? FindTypeInModule(ModuleDefinition module, string? ns, string name)
private TypeDefinition? FindTypeInModule(ModuleDefinition module, Utf8String? ns, Utf8String name)
{
for (int i = 0; i < module.ExportedTypes.Count; i++)
{
var exportedType = module.ExportedTypes[i];
if (exportedType.IsTypeOf(ns, name))
if (exportedType.IsTypeOfUtf8(ns, name))
return ResolveExportedType(exportedType);
}

for (int i = 0; i < module.TopLevelTypes.Count; i++)
{
var type = module.TopLevelTypes[i];
if (type.IsTypeOf(ns, name))
if (type.IsTypeOfUtf8(ns, name))
return type;
}

return null;
}

private static TypeDefinition? FindTypeInType(TypeDefinition enclosingType, string name)
private static TypeDefinition? FindTypeInType(TypeDefinition enclosingType, Utf8String name)
{
for (int i = 0; i < enclosingType.NestedTypes.Count; i++)
{
Expand All @@ -266,7 +270,7 @@ public TypeResolution(IAssemblyResolver resolver)
return null;
}

private static ModuleDefinition? FindModuleInAssembly(AssemblyDefinition assembly, string name)
private static ModuleDefinition? FindModuleInAssembly(AssemblyDefinition assembly, Utf8String name)
{
for (int i = 0; i < assembly.Modules.Count; i++)
{
Expand Down
8 changes: 8 additions & 0 deletions src/AsmResolver.DotNet/IFieldDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ namespace AsmResolver.DotNet
/// </summary>
public interface IFieldDescriptor : IMemberDescriptor, IMetadataMember
{
/// <summary>
/// Gets the name of the field.
/// </summary>
new Utf8String Name
{
get;
}

/// <summary>
/// Gets the signature of the field.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/AsmResolver.DotNet/IMethodDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ namespace AsmResolver.DotNet
/// </summary>
public interface IMethodDescriptor : IMemberDescriptor, IMetadataMember
{
/// <summary>
/// Gets the name of the method.
/// </summary>
new Utf8String Name
{
get;
}

/// <summary>
/// Gets the signature of the method.
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions src/AsmResolver.DotNet/TypeDescriptorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ public static class TypeDescriptorExtensions
public static bool IsTypeOf(this ITypeDescriptor type, string? ns, string? name) =>
type.Name == name && type.Namespace == ns;

/// <summary>
/// Determines whether a type matches a namespace and name pair.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="ns">The namespace.</param>
/// <param name="name">The name.</param>
/// <returns><c>true</c> if the name and the namespace of the type matches the provided values,
/// <c>false</c> otherwise.</returns>
public static bool IsTypeOfUtf8(this ITypeDefOrRef type, Utf8String? ns, Utf8String? name) =>
type.Name == name && type.Namespace == ns;

/// <summary>
/// Determines whether a type matches a namespace and name pair.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="ns">The namespace.</param>
/// <param name="name">The name.</param>
/// <returns><c>true</c> if the name and the namespace of the type matches the provided values,
/// <c>false</c> otherwise.</returns>
public static bool IsTypeOfUtf8(this ExportedType type, Utf8String? ns, Utf8String? name) =>
type.Name == name && type.Namespace == ns;

/// <summary>
/// Constructs a new single-dimension, zero based array signature with the provided type descriptor
/// as element type.
Expand Down

0 comments on commit baf25ac

Please sign in to comment.