Skip to content

Commit be89af3

Browse files
committed
Use AddComponentService in ExtractInterfaceRefactoringBase
Also adds @interface annotations to the interfaces.
1 parent 12a06ee commit be89af3

File tree

4 files changed

+65
-35
lines changed

4 files changed

+65
-35
lines changed

Rubberduck.Refactorings/ExtractInterface/ExtractInterfaceRefactoringAction.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using Antlr4.Runtime;
44
using Rubberduck.Parsing;
5+
using Rubberduck.Parsing.Annotations;
56
using Rubberduck.Parsing.Grammar;
67
using Rubberduck.Parsing.Rewriter;
78
using Rubberduck.Parsing.Symbols;
@@ -11,6 +12,7 @@
1112
using Rubberduck.VBEditor.ComManagement;
1213
using Rubberduck.VBEditor.SafeComWrappers;
1314
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
15+
using Rubberduck.VBEditor.Utility;
1416

1517
namespace Rubberduck.Refactorings.ExtractInterface
1618
{
@@ -19,18 +21,21 @@ public class ExtractInterfaceRefactoringAction : RefactoringActionWithSuspension
1921
private readonly ICodeOnlyRefactoringAction<AddInterfaceImplementationsModel> _addImplementationsRefactoringAction;
2022
private readonly IParseTreeProvider _parseTreeProvider;
2123
private readonly IProjectsProvider _projectsProvider;
24+
private readonly IAddComponentService _addComponentService;
2225

2326
public ExtractInterfaceRefactoringAction(
2427
AddInterfaceImplementationsRefactoringAction addImplementationsRefactoringAction,
2528
IParseTreeProvider parseTreeProvider,
2629
IParseManager parseManager,
2730
IRewritingManager rewritingManager,
28-
IProjectsProvider projectsProvider)
31+
IProjectsProvider projectsProvider,
32+
IAddComponentService addComponentService)
2933
: base(parseManager, rewritingManager)
3034
{
3135
_addImplementationsRefactoringAction = addImplementationsRefactoringAction;
3236
_parseTreeProvider = parseTreeProvider;
3337
_projectsProvider = projectsProvider;
38+
_addComponentService = addComponentService;
3439
}
3540

3641
protected override bool RequiresSuspension(ExtractInterfaceModel model)
@@ -51,30 +56,28 @@ private void AddInterface(ExtractInterfaceModel model, IRewriteSession rewriteSe
5156
return; //The target project is not available.
5257
}
5358

54-
AddInterfaceClass(targetProject, model.InterfaceName, GetInterfaceModuleBody(model));
59+
AddInterfaceClass(model);
5560
AddImplementsStatement(model, rewriteSession);
5661
AddInterfaceMembersToClass(model, rewriteSession);
5762
}
5863

59-
private void AddInterfaceClass(IVBProject targetProject, string interfaceName, string interfaceBody)
64+
private void AddInterfaceClass(ExtractInterfaceModel model)
6065
{
61-
using (var components = targetProject.VBComponents)
62-
{
63-
using (var interfaceComponent = components.Add(ComponentType.ClassModule))
64-
{
65-
using (var interfaceModule = interfaceComponent.CodeModule)
66-
{
67-
interfaceComponent.Name = interfaceName;
68-
69-
var optionPresent = interfaceModule.CountOfLines > 1;
70-
if (!optionPresent)
71-
{
72-
interfaceModule.InsertLines(1, $"{Tokens.Option} {Tokens.Explicit}{Environment.NewLine}");
73-
}
74-
interfaceModule.InsertLines(3, interfaceBody);
75-
}
76-
}
77-
}
66+
var targetProjectId = model.TargetDeclaration.ProjectId;
67+
var interfaceCode = InterfaceModuleBody(model);
68+
var interfaceName = model.InterfaceName;
69+
70+
_addComponentService.AddComponent(targetProjectId, ComponentType.ClassModule, interfaceCode, componentName: interfaceName);
71+
}
72+
73+
private static string InterfaceModuleBody(ExtractInterfaceModel model)
74+
{
75+
var interfaceMembers = string.Join(Environment.NewLine, model.SelectedMembers.Select(m => m.Body));
76+
var optionExplicit = $"{Tokens.Option} {Tokens.Explicit}{Environment.NewLine}";
77+
var interfaceAnnotation = new InterfaceAnnotation();
78+
var interfaceAnnotationText = $"'@{interfaceAnnotation.Name}{Environment.NewLine}";
79+
80+
return $"{optionExplicit}{Environment.NewLine}{interfaceAnnotationText}{Environment.NewLine}{interfaceMembers}";
7881
}
7982

8083
private void AddImplementsStatement(ExtractInterfaceModel model, IRewriteSession rewriteSession)
@@ -134,11 +137,6 @@ private void AddInterfaceMembersToClass(ExtractInterfaceModel model, IRewriteSes
134137
_addImplementationsRefactoringAction.Refactor(addMembersModel, rewriteSession);
135138
}
136139

137-
private static string GetInterfaceModuleBody(ExtractInterfaceModel model)
138-
{
139-
return string.Join(Environment.NewLine, model.SelectedMembers.Select(m => m.Body));
140-
}
141-
142140
private static readonly DeclarationType[] ModuleTypes =
143141
{
144142
DeclarationType.ClassModule,

RubberduckTests/CodeExplorer/MockedCodeExplorer.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,13 +504,20 @@ public MockedCodeExplorer ImplementIndenterCommand()
504504
public MockedCodeExplorer ImplementExtractInterfaceCommand()
505505
{
506506
var addImplementationsBaseRefactoring = new AddInterfaceImplementationsRefactoringAction(null);
507-
var extractInterfaceBaseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, State, State, null, State.ProjectsProvider);
507+
var addComponentService = TestAddComponentService(State.ProjectsProvider);
508+
var extractInterfaceBaseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, State, State, null, State.ProjectsProvider, addComponentService);
508509
ViewModel.CodeExplorerExtractInterfaceCommand = new CodeExplorerExtractInterfaceCommand(
509510
new ExtractInterfaceRefactoring(extractInterfaceBaseRefactoring, State, null, null, _uiDispatcher.Object),
510511
State, null, VbeEvents.Object);
511512
return this;
512513
}
513514

515+
private static IAddComponentService TestAddComponentService(IProjectsProvider projectsProvider)
516+
{
517+
var sourceCodeHandler = new CodeModuleComponentSourceCodeHandler();
518+
return new AddComponentService(projectsProvider, sourceCodeHandler, sourceCodeHandler);
519+
}
520+
514521
public MockedCodeExplorer ConfigureSaveDialog(string path, DialogResult result)
515522
{
516523
SaveDialog.Setup(o => o.FileName).Returns(path);

RubberduckTests/Commands/RefactorCommands/ExtractInterfaceCommandTests.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
using Rubberduck.UI.Command.Refactorings;
1313
using Rubberduck.UI.Command.Refactorings.Notifiers;
1414
using Rubberduck.VBEditor;
15+
using Rubberduck.VBEditor.ComManagement;
1516
using Rubberduck.VBEditor.SafeComWrappers;
1617
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
18+
using Rubberduck.VBEditor.SourceCodeHandling;
1719
using Rubberduck.VBEditor.Utility;
1820
using RubberduckTests.Mocks;
1921

@@ -172,12 +174,19 @@ protected override CommandBase TestCommand(IVBE vbe, RubberduckParserState state
172174
.Setup(m => m.Invoke(It.IsAny<Action>()))
173175
.Callback((Action action) => action.Invoke());
174176
var addImplementationsBaseRefactoring = new AddInterfaceImplementationsRefactoringAction(rewritingManager);
175-
var baseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, state, state, rewritingManager, state.ProjectsProvider);
177+
var addComponentService = TestAddComponentService(state.ProjectsProvider);
178+
var baseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, state, state, rewritingManager, state.ProjectsProvider, addComponentService);
176179
var refactoring = new ExtractInterfaceRefactoring(baseRefactoring, state, factory, selectionService, uiDispatcherMock.Object);
177180
var notifier = new ExtractInterfaceFailedNotifier(msgBox);
178181
return new RefactorExtractInterfaceCommand(refactoring, notifier, state, selectionService);
179182
}
180183

184+
private static IAddComponentService TestAddComponentService(IProjectsProvider projectsProvider)
185+
{
186+
var sourceCodeHandler = new CodeModuleComponentSourceCodeHandler();
187+
return new AddComponentService(projectsProvider, sourceCodeHandler, sourceCodeHandler);
188+
}
189+
181190
protected override IVBE SetupAllowingExecution()
182191
{
183192
const string input =

RubberduckTests/Refactoring/ExtractInterfaceTests.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
using Rubberduck.Refactorings.Exceptions;
1313
using Rubberduck.Refactorings.ExtractInterface;
1414
using Rubberduck.VBEditor;
15+
using Rubberduck.VBEditor.ComManagement;
1516
using Rubberduck.VBEditor.SafeComWrappers;
17+
using Rubberduck.VBEditor.SourceCodeHandling;
1618
using Rubberduck.VBEditor.Utility;
1719
using RubberduckTests.Mocks;
1820

@@ -47,9 +49,10 @@ End Sub
4749
const string expectedInterfaceCode =
4850
@"Option Explicit
4951
52+
'@Interface
53+
5054
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
5155
End Sub
52-
5356
";
5457
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
5558
{
@@ -194,6 +197,8 @@ End Property
194197
const string expectedInterfaceCode =
195198
@"Option Explicit
196199
200+
'@Interface
201+
197202
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
198203
End Sub
199204
@@ -208,7 +213,6 @@ End Property
208213
209214
Public Property Set Buzz(ByRef value As Variant)
210215
End Property
211-
212216
";
213217
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
214218
{
@@ -281,12 +285,13 @@ End Function
281285
const string expectedInterfaceCode =
282286
@"Option Explicit
283287
288+
'@Interface
289+
284290
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
285291
End Sub
286292
287293
Public Function Fizz(ByRef b As Variant) As Variant
288294
End Function
289-
290295
";
291296
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
292297
{
@@ -401,9 +406,10 @@ End Sub
401406
const string expectedInterfaceCode =
402407
@"Option Explicit
403408
409+
'@Interface
410+
404411
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
405412
End Sub
406-
407413
";
408414
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
409415
{
@@ -466,9 +472,10 @@ End Sub
466472
const string expectedInterfaceCode =
467473
@"Option Explicit
468474
475+
'@Interface
476+
469477
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
470478
End Sub
471-
472479
";
473480
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
474481
{
@@ -545,9 +552,10 @@ End Sub
545552
const string expectedInterfaceCode =
546553
@"Option Explicit
547554
555+
'@Interface
556+
548557
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
549558
End Sub
550-
551559
";
552560
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
553561
{
@@ -622,9 +630,10 @@ End Sub
622630
const string expectedInterfaceCode =
623631
@"Option Explicit
624632
633+
'@Interface
634+
625635
Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
626636
End Sub
627-
628637
";
629638
Func<ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
630639
{
@@ -650,8 +659,15 @@ protected override IRefactoring TestRefactoring(IRewritingManager rewritingManag
650659
.Setup(m => m.Invoke(It.IsAny<Action>()))
651660
.Callback((Action action) => action.Invoke());
652661
var addImplementationsBaseRefactoring = new AddInterfaceImplementationsRefactoringAction(rewritingManager);
653-
var baseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, state, state, rewritingManager, state?.ProjectsProvider);
662+
var addComponentService = TestAddComponentService(state?.ProjectsProvider);
663+
var baseRefactoring = new ExtractInterfaceRefactoringAction(addImplementationsBaseRefactoring, state, state, rewritingManager, state?.ProjectsProvider, addComponentService);
654664
return new ExtractInterfaceRefactoring(baseRefactoring, state, factory, selectionService, uiDispatcherMock.Object);
655665
}
666+
667+
private static IAddComponentService TestAddComponentService(IProjectsProvider projectsProvider)
668+
{
669+
var sourceCodeHandler = new CodeModuleComponentSourceCodeHandler();
670+
return new AddComponentService(projectsProvider, sourceCodeHandler, sourceCodeHandler);
671+
}
656672
}
657673
}

0 commit comments

Comments
 (0)