Skip to content

Commit

Permalink
Optimize finding CustomAttribute by a full name (#527)
Browse files Browse the repository at this point in the history
* Optimize finding CustomAttribute by a full name

* Revert newlines

* Check if fullName is null
  • Loading branch information
AlanLiu90 authored Sep 20, 2023
1 parent efba133 commit aac31a1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
22 changes: 20 additions & 2 deletions src/DotNet/CustomAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,26 @@ public string TypeFullName {

return string.Empty;
}
}

}

/// <summary>
/// Gets the name of the attribute type
/// </summary>
internal string TypeName {
get {
if (ctor is MemberRef mrCtor)
return mrCtor.GetDeclaringTypeName() ?? string.Empty;

if (ctor is MethodDef mdCtor) {
var declType = mdCtor.DeclaringType;
if (declType is not null)
return declType.Name;
}

return string.Empty;
}
}

/// <summary>
/// <c>true</c> if the raw custom attribute blob hasn't been parsed
/// </summary>
Expand Down
16 changes: 13 additions & 3 deletions src/DotNet/CustomAttributeCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ public CustomAttributeCollection(int length, object context, Func<object, int, C
/// </summary>
/// <param name="fullName">Full name of custom attribute type that should be removed</param>
public void RemoveAll(string fullName) {
if (fullName == null)
return;

for (int i = Count - 1; i >= 0; i--) {
if (this[i].TypeFullName == fullName)
var ca = this[i];
if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName)
RemoveAt(i);
}
}
Expand All @@ -49,8 +53,11 @@ public void RemoveAll(string fullName) {
/// <param name="fullName">Full name of custom attribute type</param>
/// <returns>A <see cref="CustomAttribute"/> or <c>null</c> if it wasn't found</returns>
public CustomAttribute Find(string fullName) {
if (fullName == null)
return null;

foreach (var ca in this) {
if (ca is not null && ca.TypeFullName == fullName)
if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName)
return ca;
}

Expand All @@ -63,8 +70,11 @@ public CustomAttribute Find(string fullName) {
/// <param name="fullName">Full name of custom attribute type</param>
/// <returns>All <see cref="CustomAttribute"/>s of the requested type</returns>
public IEnumerable<CustomAttribute> FindAll(string fullName) {
if (fullName == null)
yield break;

foreach (var ca in this) {
if (ca is not null && ca.TypeFullName == fullName)
if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName)
yield return ca;
}
}
Expand Down
24 changes: 22 additions & 2 deletions src/DotNet/MemberRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,28 @@ string GetDeclaringTypeFullName(IMemberRefParent parent) {
return declaringType?.FullName;
}
return null; // Should never be reached
}

}

/// <summary>
/// Get the declaring type's name
/// </summary>
/// <returns>Name or <c>null</c> if there's no declaring type</returns>
internal string GetDeclaringTypeName() => GetDeclaringTypeName(@class);

string GetDeclaringTypeName(IMemberRefParent parent) {
if (parent is null)
return null;
if (parent is ITypeDefOrRef)
return ((ITypeDefOrRef)parent).Name;
if (parent is ModuleRef)
return $"<Module>";
if (parent is MethodDef) {
var declaringType = ((MethodDef)parent).DeclaringType;
return declaringType?.Name;
}
return null; // Should never be reached
}

/// <summary>
/// Resolves the method/field
/// </summary>
Expand Down

0 comments on commit aac31a1

Please sign in to comment.