Skip to content

Commit 047fd73

Browse files
committed
Move EncapsulateField to the ISelectionService
1 parent ae1442f commit 047fd73

File tree

6 files changed

+108
-133
lines changed

6 files changed

+108
-133
lines changed

Rubberduck.CodeAnalysis/QuickFixes/EncapsulateFieldQuickFix.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,23 @@
77
using Rubberduck.Refactorings.EncapsulateField;
88
using Rubberduck.SmartIndenter;
99
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
10+
using Rubberduck.VBEditor.Utility;
1011

1112
namespace Rubberduck.Inspections.QuickFixes
1213
{
1314
public sealed class EncapsulateFieldQuickFix : QuickFixBase
1415
{
1516
private readonly RubberduckParserState _state;
16-
private readonly IVBE _vbe;
17+
private readonly ISelectionService _selectionService;
1718
private readonly IRewritingManager _rewritingManager;
1819
private readonly IIndenter _indenter;
1920
private readonly IRefactoringPresenterFactory _factory;
2021

21-
public EncapsulateFieldQuickFix(RubberduckParserState state, IVBE vbe, IIndenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager)
22+
public EncapsulateFieldQuickFix(RubberduckParserState state, IIndenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager, ISelectionService selectionService)
2223
: base(typeof(EncapsulatePublicFieldInspection))
2324
{
2425
_state = state;
25-
_vbe = vbe;
26+
_selectionService = selectionService;
2627
_rewritingManager = rewritingManager;
2728
_indenter = indenter;
2829
_factory = factory;
@@ -31,7 +32,7 @@ public EncapsulateFieldQuickFix(RubberduckParserState state, IVBE vbe, IIndenter
3132
//The rewriteSession is optional since it is not used in this particular quickfix because it is a refactoring quickfix.
3233
public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null)
3334
{
34-
var refactoring = new EncapsulateFieldRefactoring(_state, _vbe, _indenter, _factory, _rewritingManager);
35+
var refactoring = new EncapsulateFieldRefactoring(_state, _indenter, _factory, _rewritingManager, _selectionService);
3536
refactoring.Refactor(result.Target);
3637
}
3738

Rubberduck.Core/UI/Command/Refactorings/RefactorEncapsulateFieldCommand.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
using Rubberduck.Refactorings;
66
using Rubberduck.Refactorings.EncapsulateField;
77
using Rubberduck.SmartIndenter;
8-
using Rubberduck.UI.Refactorings.EncapsulateField;
98
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
9+
using Rubberduck.VBEditor.Utility;
1010

1111
namespace Rubberduck.UI.Command.Refactorings
1212
{
@@ -15,30 +15,36 @@ public class RefactorEncapsulateFieldCommand : RefactorCommandBase
1515
{
1616
private readonly RubberduckParserState _state;
1717
private readonly IRewritingManager _rewritingManager;
18+
private readonly ISelectionService _selectionService;
1819
private readonly Indenter _indenter;
1920
private readonly IRefactoringPresenterFactory _factory;
2021

21-
public RefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, Indenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager)
22+
public RefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, Indenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager, ISelectionService selectionService)
2223
: base(vbe)
2324
{
2425
_state = state;
2526
_rewritingManager = rewritingManager;
2627
_indenter = indenter;
2728
_factory = factory;
29+
_selectionService = selectionService;
2830
}
2931

3032
protected override bool EvaluateCanExecute(object parameter)
3133
{
32-
Declaration target;
33-
using (var pane = Vbe.ActiveCodePane)
34+
//This should come first because it does not require COM access.
35+
if (_state.Status != ParserState.Ready)
3436
{
35-
if (pane == null || _state.Status != ParserState.Ready)
36-
{
37-
return false;
38-
}
37+
return false;
38+
}
3939

40-
target = _state.FindSelectedDeclaration(pane);
40+
var activeSelection = _selectionService.ActiveSelection();
41+
if (!activeSelection.HasValue)
42+
{
43+
return false;
4144
}
45+
46+
var target = _state.DeclarationFinder.FindSelectedDeclaration(activeSelection.Value);
47+
4248
return target != null
4349
&& target.DeclarationType == DeclarationType.Variable
4450
&& !target.ParentScopeDeclaration.DeclarationType.HasFlag(DeclarationType.Member)
@@ -47,15 +53,12 @@ protected override bool EvaluateCanExecute(object parameter)
4753

4854
protected override void OnExecute(object parameter)
4955
{
50-
using(var activePane = Vbe.ActiveCodePane)
56+
if(!_selectionService.ActiveSelection().HasValue)
5157
{
52-
if (activePane == null || activePane.IsWrappingNullReference)
53-
{
54-
return;
55-
}
58+
return;
5659
}
5760

58-
var refactoring = new EncapsulateFieldRefactoring(_state, Vbe, _indenter, _factory, _rewritingManager);
61+
var refactoring = new EncapsulateFieldRefactoring(_state, _indenter, _factory, _rewritingManager, _selectionService);
5962
refactoring.Refactor();
6063
}
6164
}

Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -269,25 +269,14 @@ private IDictionary<Declaration, List<Declaration>> FindAllHandlersByWithEventFi
269269
return handlersByWithEventsField;
270270
}
271271

272-
public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
272+
public Declaration FindSelectedDeclaration(QualifiedSelection qualifiedSelection)
273273
{
274-
if (activeCodePane == null || activeCodePane.IsWrappingNullReference)
275-
{
276-
return null;
277-
}
278-
279-
var qualifiedSelection = activeCodePane.GetQualifiedSelection();
280-
if (!qualifiedSelection.HasValue || qualifiedSelection.Value.Equals(default))
281-
{
282-
return null;
283-
}
284-
285-
var selection = qualifiedSelection.Value.Selection;
274+
var selection = qualifiedSelection.Selection;
286275

287276
// statistically we'll be on an IdentifierReference more often than on a Declaration:
288277
var matches = _referencesBySelection
289-
.Where(kvp => kvp.Key.QualifiedName.Equals(qualifiedSelection.Value.QualifiedName)
290-
&& kvp.Key.Selection.ContainsFirstCharacter(qualifiedSelection.Value.Selection))
278+
.Where(kvp => kvp.Key.QualifiedName.Equals(qualifiedSelection.QualifiedName)
279+
&& kvp.Key.Selection.ContainsFirstCharacter(qualifiedSelection.Selection))
291280
.SelectMany(kvp => kvp.Value)
292281
.OrderByDescending(reference => reference.Declaration.DeclarationType)
293282
.Select(reference => reference.Declaration)
@@ -297,8 +286,8 @@ public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
297286
if (!matches.Any())
298287
{
299288
matches = _declarationsBySelection
300-
.Where(kvp => kvp.Key.QualifiedName.Equals(qualifiedSelection.Value.QualifiedName)
301-
&& kvp.Key.Selection.ContainsFirstCharacter(selection))
289+
.Where(kvp => kvp.Key.QualifiedName.Equals(qualifiedSelection.QualifiedName)
290+
&& kvp.Key.Selection.ContainsFirstCharacter(selection))
302291
.SelectMany(kvp => kvp.Value)
303292
.OrderByDescending(declaration => declaration.DeclarationType)
304293
.Distinct()
@@ -308,7 +297,7 @@ public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
308297
switch (matches.Length)
309298
{
310299
case 0:
311-
return ModuleDeclaration(qualifiedSelection.Value.QualifiedName);
300+
return ModuleDeclaration(qualifiedSelection.QualifiedName);
312301

313302
case 1:
314303
return matches.Single();
@@ -319,6 +308,22 @@ public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
319308
}
320309
}
321310

311+
public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
312+
{
313+
if (activeCodePane == null || activeCodePane.IsWrappingNullReference)
314+
{
315+
return null;
316+
}
317+
318+
var qualifiedSelection = activeCodePane.GetQualifiedSelection();
319+
if (!qualifiedSelection.HasValue || qualifiedSelection.Value.Equals(default))
320+
{
321+
return null;
322+
}
323+
324+
return FindSelectedDeclaration(qualifiedSelection.Value);
325+
}
326+
322327
public IEnumerable<Declaration> FreshUndeclared => _newUndeclared.AllValues();
323328

324329
//This does not need a lock because enumerators over a ConcurrentBag uses a snapshot.

Rubberduck.Refactorings/EncapsulateField/EncapsulateFieldRefactoring.cs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ namespace Rubberduck.Refactorings.EncapsulateField
1717
public class EncapsulateFieldRefactoring : IRefactoring
1818
{
1919
private readonly RubberduckParserState _state;
20-
private readonly IVBE _vbe;
2120
private readonly IIndenter _indenter;
2221
private readonly IRewritingManager _rewritingManager;
22+
private readonly ISelectionService _selectionService;
2323
private readonly IRefactoringPresenterFactory _factory;
2424
private EncapsulateFieldModel _model;
2525

26-
public EncapsulateFieldRefactoring(RubberduckParserState state, IVBE vbe, IIndenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager)
26+
public EncapsulateFieldRefactoring(RubberduckParserState state, IIndenter indenter, IRefactoringPresenterFactory factory, IRewritingManager rewritingManager, ISelectionService selectionService)
2727
{
2828
_state = state;
29-
_vbe = vbe;
3029
_indenter = indenter;
3130
_factory = factory;
3231
_rewritingManager = rewritingManager;
32+
_selectionService = selectionService;
3333
}
3434

3535
private EncapsulateFieldModel InitializeModel()
3636
{
37-
var selection = _vbe.GetActiveSelection();
37+
var selection = _selectionService.ActiveSelection();
3838

3939
if (!selection.HasValue)
4040
{
@@ -74,29 +74,16 @@ public void Refactor()
7474

7575
public void Refactor(QualifiedSelection target)
7676
{
77-
using (var pane = _vbe.ActiveCodePane)
77+
if (!_selectionService.TrySetActiveSelection(target))
7878
{
79-
if (pane == null || pane.IsWrappingNullReference)
80-
{
81-
return;
82-
}
83-
pane.Selection = target.Selection;
79+
return;
8480
}
8581
Refactor();
8682
}
8783

8884
public void Refactor(Declaration target)
8985
{
90-
using (var pane = _vbe.ActiveCodePane)
91-
{
92-
if (pane == null || pane.IsWrappingNullReference)
93-
{
94-
return;
95-
}
96-
97-
pane.Selection = target.QualifiedSelection.Selection;
98-
}
99-
Refactor();
86+
Refactor(target.QualifiedSelection);
10087
}
10188

10289
private void AddProperty(IRewriteSession rewriteSession)

RubberduckTests/Commands/RefactorCommandTests.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
99
using RubberduckTests.Mocks;
1010
using Rubberduck.Interaction;
11+
using Rubberduck.Parsing.Rewriter;
1112
using Rubberduck.Refactorings;
13+
using Rubberduck.VBEditor.Utility;
1214

1315
namespace RubberduckTests.Commands
1416
{
@@ -25,8 +27,7 @@ public void EncapsulateField_CanExecute_NullActiveCodePane()
2527
var (state, rewritingManager) = MockParser.CreateAndParseWithRewritingManager(vbe.Object);
2628
using (state)
2729
{
28-
var factory = new Mock<IRefactoringPresenterFactory>();
29-
var encapsulateFieldCommand = new RefactorEncapsulateFieldCommand(vbe.Object, state, null, factory.Object, rewritingManager);
30+
var encapsulateFieldCommand = TestRefactorEncapsulateFieldCommand(vbe.Object, state, rewritingManager);
3031
Assert.IsFalse(encapsulateFieldCommand.CanExecute(null));
3132
}
3233
}
@@ -41,9 +42,8 @@ public void EncapsulateField_CanExecute_NonReadyState()
4142
using (state)
4243
{
4344
state.SetStatusAndFireStateChanged(this, ParserState.ResolvedDeclarations, CancellationToken.None);
44-
45-
var factory = new Mock<IRefactoringPresenterFactory>();
46-
var encapsulateFieldCommand = new RefactorEncapsulateFieldCommand(vbe.Object, state, null, factory.Object, rewritingManager);
45+
46+
var encapsulateFieldCommand = TestRefactorEncapsulateFieldCommand(vbe.Object, state, rewritingManager);
4747
Assert.IsFalse(encapsulateFieldCommand.CanExecute(null));
4848
}
4949
}
@@ -61,8 +61,7 @@ Dim d As Boolean
6161
var (state, rewritingManager) = MockParser.CreateAndParseWithRewritingManager(vbe.Object);
6262
using (state)
6363
{
64-
var factory = new Mock<IRefactoringPresenterFactory>();
65-
var encapsulateFieldCommand = new RefactorEncapsulateFieldCommand(vbe.Object, state, null, factory.Object, rewritingManager);
64+
var encapsulateFieldCommand = TestRefactorEncapsulateFieldCommand(vbe.Object, state, rewritingManager);
6665
Assert.IsFalse(encapsulateFieldCommand.CanExecute(null));
6766
}
6867
}
@@ -80,8 +79,7 @@ Sub Foo()
8079
var (state, rewritingManager) = MockParser.CreateAndParseWithRewritingManager(vbe.Object);
8180
using (state)
8281
{
83-
var factory = new Mock<IRefactoringPresenterFactory>();
84-
var encapsulateFieldCommand = new RefactorEncapsulateFieldCommand(vbe.Object, state, null, factory.Object, rewritingManager);
82+
var encapsulateFieldCommand = TestRefactorEncapsulateFieldCommand(vbe.Object, state, rewritingManager);
8583
Assert.IsFalse(encapsulateFieldCommand.CanExecute(null));
8684
}
8785
}
@@ -99,12 +97,19 @@ Sub Foo()
9997
var (state, rewritingManager) = MockParser.CreateAndParseWithRewritingManager(vbe.Object);
10098
using (state)
10199
{
102-
var factory = new Mock<IRefactoringPresenterFactory>();
103-
var encapsulateFieldCommand = new RefactorEncapsulateFieldCommand(vbe.Object, state, null, factory.Object, rewritingManager);
100+
var encapsulateFieldCommand = TestRefactorEncapsulateFieldCommand(vbe.Object, state, rewritingManager);
104101
Assert.IsTrue(encapsulateFieldCommand.CanExecute(null));
105102
}
106103
}
107104

105+
private RefactorEncapsulateFieldCommand TestRefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, IRewritingManager rewritingManager)
106+
{
107+
var factory = new Mock<IRefactoringPresenterFactory>().Object;
108+
var selectionService = new Mock<ISelectionService>().Object;
109+
return new RefactorEncapsulateFieldCommand(vbe, state, null, factory, rewritingManager, selectionService);
110+
}
111+
112+
108113
[Category("Commands")]
109114
[Test]
110115
public void ExtractInterface_CanExecute_NullActiveCodePane()

0 commit comments

Comments
 (0)