Skip to content

Commit 84b7a68

Browse files
committed
Add EncapsulateFieldCandidateCollectionProvider
Adds and registers the EncapsulateFieldCandidateCollectionProviderFactory as well.
1 parent 05e5304 commit 84b7a68

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed

Rubberduck.Main/Root/RubberduckIoCInstaller.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ private void RegisterEncapsulateFieldRefactoringFactories(IWindsorContainer cont
411411
container.Register(Component.For<IEncapsulateFieldModelFactory>()
412412
.ImplementedBy<EncapsulateFieldModelFactory>()
413413
.LifestyleSingleton());
414-
container.Register(Component.For<IEncapsulateFieldCandidateCollectionFactory>()
415-
.ImplementedBy<EncapsulateFieldCandidateCollectionFactory>()
414+
container.Register(Component.For<IEncapsulateFieldCollectionsProviderFactory>()
415+
.ImplementedBy<EncapsulateFieldCollectionsProviderFactory>()
416416
.LifestyleSingleton());
417417
container.Register(Component.For<IObjectStateUserDefinedTypeFactory>()
418418
.ImplementedBy<ObjectStateUserDefinedTypeFactory>()
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using Rubberduck.Parsing.Symbols;
2+
using Rubberduck.Parsing.VBA;
3+
using Rubberduck.VBEditor;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace Rubberduck.Refactorings.EncapsulateField
8+
{
9+
public interface IEncapsulateFieldCollectionsProvider
10+
{
11+
IReadOnlyCollection<IEncapsulateFieldCandidate> EncapsulateFieldCandidates { get; }
12+
IReadOnlyCollection<IEncapsulateFieldAsUDTMemberCandidate> EncapsulateAsUserDefinedTypeMemberCandidates { get; }
13+
IReadOnlyCollection<IObjectStateUDT> ObjectStateUDTCandidates { get; }
14+
}
15+
16+
/// <summary>
17+
/// EncapsulateFieldCollectionsProvider generates collections IEncapsulateFieldCandidate
18+
/// instances, IEncapsulateFieldAsUDTMemberCandidate instances, and IObjectStateUDT instances.
19+
/// It provides these collections to the various objects of the EncapsulateFieldRefactoring
20+
/// so that they all operate in the same object sets.
21+
/// </summary>
22+
/// <remarks>
23+
/// The EncapsulateFieldCollectionsProvider is the source of these collections for the various objects of
24+
/// the EncapsulateFieldRefactoring so that they all operate in the same set of object instances.
25+
/// </remarks>
26+
public class EncapsulateFieldCollectionsProvider : IEncapsulateFieldCollectionsProvider
27+
{
28+
private readonly IDeclarationFinderProvider _declarationFinderProvider;
29+
private readonly IEncapsulateFieldCandidateFactory _encapsulateFieldCandidateFactory;
30+
private readonly IObjectStateUserDefinedTypeFactory _objectStateUserDefinedTypeFactory;
31+
32+
public EncapsulateFieldCollectionsProvider(
33+
IDeclarationFinderProvider declarationFinderProvider,
34+
IEncapsulateFieldCandidateFactory encapsulateFieldCandidateFactory,
35+
IObjectStateUserDefinedTypeFactory objectStateUserDefinedTypeFactory,
36+
QualifiedModuleName qualifiedModuleName)
37+
{
38+
_declarationFinderProvider = declarationFinderProvider;
39+
_encapsulateFieldCandidateFactory = encapsulateFieldCandidateFactory;
40+
_objectStateUserDefinedTypeFactory = objectStateUserDefinedTypeFactory;
41+
42+
EncapsulateFieldCandidates = _declarationFinderProvider.DeclarationFinder.Members(qualifiedModuleName, DeclarationType.Variable)
43+
.Where(v => v.ParentDeclaration is ModuleDeclaration
44+
&& !v.IsWithEvents)
45+
.Select(f => _encapsulateFieldCandidateFactory.Create(f))
46+
.ToList();
47+
48+
ObjectStateUDTCandidates = LoadObjectStateUDTCandidates(EncapsulateFieldCandidates, _objectStateUserDefinedTypeFactory, qualifiedModuleName);
49+
50+
EncapsulateAsUserDefinedTypeMemberCandidates = LoadAsUDTMemberCandidates(EncapsulateFieldCandidates, ObjectStateUDTCandidates);
51+
}
52+
53+
public IReadOnlyCollection<IEncapsulateFieldCandidate> EncapsulateFieldCandidates { get; }
54+
55+
public IReadOnlyCollection<IEncapsulateFieldAsUDTMemberCandidate> EncapsulateAsUserDefinedTypeMemberCandidates { get; }
56+
57+
public IReadOnlyCollection<IObjectStateUDT> ObjectStateUDTCandidates { get; }
58+
59+
private static List<IObjectStateUDT> LoadObjectStateUDTCandidates(IReadOnlyCollection<IEncapsulateFieldCandidate> fieldCandidates, IObjectStateUserDefinedTypeFactory factory, QualifiedModuleName qmn)
60+
{
61+
var objectStateUDTs = new List<IObjectStateUDT>();
62+
objectStateUDTs = fieldCandidates
63+
.OfType<IUserDefinedTypeCandidate>()
64+
.Where(fc => fc.Declaration.Accessibility == Accessibility.Private
65+
&& fc.Declaration.AsTypeDeclaration.Accessibility == Accessibility.Private)
66+
.Select(udtc => factory.Create(udtc))
67+
.ToList();
68+
69+
//If more than one instance of a UserDefinedType is available, it is disqualified as
70+
//a field to host the module's state.
71+
var multipleFieldsOfTheSameUDT = objectStateUDTs.ToLookup(os => os.Declaration.AsTypeDeclaration.IdentifierName);
72+
foreach (var duplicate in multipleFieldsOfTheSameUDT.Where(d => d.Count() > 1))
73+
{
74+
objectStateUDTs.RemoveAll(os => duplicate.Contains(os));
75+
}
76+
77+
var defaultObjectStateUDT = factory.Create(qmn);
78+
objectStateUDTs.Add(defaultObjectStateUDT);
79+
80+
return objectStateUDTs;
81+
}
82+
83+
private static List<IEncapsulateFieldAsUDTMemberCandidate> LoadAsUDTMemberCandidates(IReadOnlyCollection<IEncapsulateFieldCandidate> fieldCandidates, IReadOnlyCollection<IObjectStateUDT> objectStateUDTCandidates)
84+
{
85+
var encapsulateAsUDTMembers = new List<IEncapsulateFieldAsUDTMemberCandidate>();
86+
var defaultObjectStateUDT = objectStateUDTCandidates.FirstOrDefault(os => !os.IsExistingDeclaration);
87+
88+
foreach (var field in fieldCandidates)
89+
{
90+
var asUDT = new EncapsulateFieldAsUDTMemberCandidate(field, defaultObjectStateUDT);
91+
encapsulateAsUDTMembers.Add(asUDT);
92+
}
93+
94+
return encapsulateAsUDTMembers;
95+
}
96+
}
97+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Rubberduck.Parsing.VBA;
2+
using Rubberduck.Refactorings.EncapsulateField;
3+
using Rubberduck.VBEditor;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace Rubberduck.Refactorings
11+
{
12+
public interface IEncapsulateFieldCollectionsProviderFactory
13+
{
14+
IEncapsulateFieldCollectionsProvider Create(QualifiedModuleName qualifiedModuleName);
15+
}
16+
17+
public class EncapsulateFieldCollectionsProviderFactory : IEncapsulateFieldCollectionsProviderFactory
18+
{
19+
private readonly IDeclarationFinderProvider _declarationFinderProvider;
20+
private readonly IEncapsulateFieldCandidateFactory _encapsulateFieldCandidateFactory;
21+
private readonly IObjectStateUserDefinedTypeFactory _objectStateUserDefinedTypeFactory;
22+
23+
public EncapsulateFieldCollectionsProviderFactory(
24+
IDeclarationFinderProvider declarationFinderProvider,
25+
IEncapsulateFieldCandidateFactory encapsulateFieldCandidateFactory,
26+
IObjectStateUserDefinedTypeFactory objectStateUserDefinedTypeFactory)
27+
{
28+
_declarationFinderProvider = declarationFinderProvider;
29+
_encapsulateFieldCandidateFactory = encapsulateFieldCandidateFactory;
30+
_objectStateUserDefinedTypeFactory = objectStateUserDefinedTypeFactory;
31+
}
32+
33+
public IEncapsulateFieldCollectionsProvider Create(QualifiedModuleName qualifiedModuleName)
34+
{
35+
return new EncapsulateFieldCollectionsProvider(
36+
_declarationFinderProvider,
37+
_encapsulateFieldCandidateFactory,
38+
_objectStateUserDefinedTypeFactory,
39+
qualifiedModuleName);
40+
}
41+
}
42+
43+
}

0 commit comments

Comments
 (0)