Skip to content

Commit 277dd42

Browse files
refactor: add field member caching to DomainResolver
Signed-off-by: Alexander Linne <alexander.linne@tngtech.com>
1 parent 7fea6aa commit 277dd42

3 files changed

Lines changed: 71 additions & 77 deletions

File tree

ArchUnitNET/Loader/DomainResolver.cs

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ internal class DomainResolver
2929
private readonly Dictionary<string, MethodMemberInstance> _allMethods =
3030
new Dictionary<string, MethodMemberInstance>();
3131

32+
private readonly Dictionary<string, FieldMember> _allFields =
33+
new Dictionary<string, FieldMember>();
34+
3235
public DomainResolver(
3336
LoadTaskRegistry loadTaskRegistry
3437
)
@@ -620,33 +623,89 @@ MethodReference methodReference
620623
}
621624

622625
[NotNull]
623-
internal FieldMember CreateStubFieldMemberFromFieldReference(
626+
internal FieldMember GetOrCreateFieldMember(
624627
[NotNull] IType type,
625628
[NotNull] FieldReference fieldReference
626629
)
627630
{
631+
var fullName = fieldReference.FullName;
632+
if (_allFields.TryGetValue(fullName, out var existing))
633+
{
634+
return existing;
635+
}
636+
628637
var typeReference = fieldReference.FieldType;
629638
var fieldType = GetOrCreateStubTypeInstanceFromTypeReference(typeReference);
630639
var isCompilerGenerated = fieldReference.IsCompilerGenerated();
631-
bool? isStatic = null;
632-
var isReadOnly = false;
640+
Visibility visibility;
641+
bool? isStatic;
642+
Writability writeAccessor;
633643

634644
if (fieldReference is FieldDefinition fieldDefinition)
635645
{
646+
visibility = GetVisibilityFromFieldDefinition(fieldDefinition);
636647
isStatic = fieldDefinition.IsStatic;
637-
isReadOnly = fieldDefinition.IsInitOnly;
648+
writeAccessor = fieldDefinition.IsInitOnly
649+
? Writability.ReadOnly
650+
: Writability.Writable;
651+
}
652+
else
653+
{
654+
visibility = Public;
655+
isStatic = null;
656+
writeAccessor = Writability.Writable;
638657
}
639658

640-
return new FieldMember(
659+
var fieldMember = new FieldMember(
641660
type,
642661
fieldReference.Name,
643-
fieldReference.FullName,
644-
Public,
662+
fullName,
663+
visibility,
645664
fieldType,
646665
isCompilerGenerated,
647666
isStatic,
648-
isReadOnly ? Writability.ReadOnly : Writability.Writable
667+
writeAccessor
649668
);
669+
670+
_allFields.Add(fullName, fieldMember);
671+
return fieldMember;
672+
}
673+
674+
private static Visibility GetVisibilityFromFieldDefinition(
675+
[NotNull] FieldDefinition fieldDefinition
676+
)
677+
{
678+
if (fieldDefinition.IsPublic)
679+
{
680+
return Public;
681+
}
682+
683+
if (fieldDefinition.IsPrivate)
684+
{
685+
return Private;
686+
}
687+
688+
if (fieldDefinition.IsFamily)
689+
{
690+
return Protected;
691+
}
692+
693+
if (fieldDefinition.IsAssembly)
694+
{
695+
return Internal;
696+
}
697+
698+
if (fieldDefinition.IsFamilyOrAssembly)
699+
{
700+
return ProtectedInternal;
701+
}
702+
703+
if (fieldDefinition.IsFamilyAndAssembly)
704+
{
705+
return PrivateProtected;
706+
}
707+
708+
throw new ArgumentException("The field definition seems to have no visibility.");
650709
}
651710

652711
public IEnumerable<GenericParameter> GetGenericParameters(

ArchUnitNET/Loader/LoadTasks/AddMembers.cs

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System;
21
using System.Collections.Generic;
32
using System.Linq;
4-
using System.Reflection;
53
using ArchUnitNET.Domain;
64
using JetBrains.Annotations;
75
using Mono.Cecil;
8-
using static ArchUnitNET.Domain.Visibility;
96

107
namespace ArchUnitNET.Loader.LoadTasks
118
{
@@ -40,7 +37,9 @@ private IEnumerable<IMember> CreateMembers([NotNull] TypeDefinition typeDefiniti
4037
{
4138
return typeDefinition
4239
.Fields.Where(fieldDefinition => !fieldDefinition.IsBackingField())
43-
.Select(CreateFieldMember)
40+
.Select(fieldDef =>
41+
(IMember)_domainResolver.GetOrCreateFieldMember(_typeInstance.Type, fieldDef)
42+
)
4443
.Concat(
4544
typeDefinition
4645
.Properties.Select(CreatePropertyMember)
@@ -58,28 +57,6 @@ private IEnumerable<IMember> CreateMembers([NotNull] TypeDefinition typeDefiniti
5857
.Where(member => !member.IsCompilerGenerated);
5958
}
6059

61-
[NotNull]
62-
private IMember CreateFieldMember([NotNull] FieldDefinition fieldDefinition)
63-
{
64-
var typeReference = fieldDefinition.FieldType;
65-
var fieldType = _domainResolver.GetOrCreateStubTypeInstanceFromTypeReference(
66-
typeReference
67-
);
68-
var visibility = GetVisibilityFromFieldDefinition(fieldDefinition);
69-
var isCompilerGenerated = fieldDefinition.IsCompilerGenerated();
70-
var writeAccessor = GetWriteAccessor(fieldDefinition);
71-
return new FieldMember(
72-
_typeInstance.Type,
73-
fieldDefinition.Name,
74-
fieldDefinition.FullName,
75-
visibility,
76-
fieldType,
77-
isCompilerGenerated,
78-
fieldDefinition.IsStatic,
79-
writeAccessor
80-
);
81-
}
82-
8360
[NotNull]
8461
private IMember CreatePropertyMember(PropertyDefinition propertyDefinition)
8562
{
@@ -103,48 +80,6 @@ private IMember CreatePropertyMember(PropertyDefinition propertyDefinition)
10380
);
10481
}
10582

106-
private static Visibility GetVisibilityFromFieldDefinition(
107-
[NotNull] FieldDefinition fieldDefinition
108-
)
109-
{
110-
if (fieldDefinition.IsPublic)
111-
{
112-
return Public;
113-
}
114-
115-
if (fieldDefinition.IsPrivate)
116-
{
117-
return Private;
118-
}
119-
120-
if (fieldDefinition.IsFamily)
121-
{
122-
return Protected;
123-
}
124-
125-
if (fieldDefinition.IsAssembly)
126-
{
127-
return Internal;
128-
}
129-
130-
if (fieldDefinition.IsFamilyOrAssembly)
131-
{
132-
return ProtectedInternal;
133-
}
134-
135-
if (fieldDefinition.IsFamilyAndAssembly)
136-
{
137-
return PrivateProtected;
138-
}
139-
140-
throw new ArgumentException("The field definition seems to have no visibility.");
141-
}
142-
143-
private static Writability GetWriteAccessor([NotNull] FieldDefinition fieldDefinition)
144-
{
145-
return fieldDefinition.IsInitOnly ? Writability.ReadOnly : Writability.Writable;
146-
}
147-
14883
private static Writability GetWriteAccessor([NotNull] PropertyDefinition propertyDefinition)
14984
{
15085
bool isReadOnly = propertyDefinition.SetMethod == null;

ArchUnitNET/Loader/MonoCecilMemberExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ DomainResolver domainResolver
250250
switch (matchingFieldMembers.Count)
251251
{
252252
case 0:
253-
var stubFieldMember = domainResolver.CreateStubFieldMemberFromFieldReference(
253+
var stubFieldMember = domainResolver.GetOrCreateFieldMember(
254254
declaringType.Type,
255255
fieldReference
256256
);

0 commit comments

Comments
 (0)