Skip to content

Commit 91a5088

Browse files
authored
Merge pull request #5387 from MDoerner/SplitRefactorings
Split refactorings
2 parents 9734c7f + f2a8b98 commit 91a5088

File tree

71 files changed

+4385
-2667
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4385
-2667
lines changed

Rubberduck.Main/Root/RubberduckIoCInstaller.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ public void Install(IWindsorContainer container, IConfigurationStore store)
149149
.LifestyleSingleton());
150150

151151
RegisterSettingsViewModel(container);
152+
RegisterRefactoringPreviewProviders(container);
152153
RegisterRefactoringDialogs(container);
153154

154155
container.Register(Component.For<ISearchResultsWindowViewModel>()
155156
.ImplementedBy<SearchResultsWindowViewModel>()
156157
.LifestyleSingleton());
157158
container.Register(Component.For<SearchResultPresenterInstanceManager>()
158159
.LifestyleSingleton());
159-
160-
RegisterRefactoringDialogs(container);
160+
161161
RegisterDockablePresenters(container);
162162
RegisterDockableUserControls(container);
163163

@@ -715,6 +715,23 @@ private void RegisterSettingsViewModel(IWindsorContainer container)
715715
);
716716
}
717717

718+
private void RegisterRefactoringPreviewProviders(IWindsorContainer container)
719+
{
720+
container.Register(Types
721+
.FromAssemblyInThisApplication()
722+
.IncludeNonPublicTypes()
723+
.BasedOn(typeof(IRefactoringPreviewProvider<>))
724+
.LifestyleSingleton()
725+
.WithServiceSelect((type, types) =>
726+
{
727+
var face = type.GetInterfaces().FirstOrDefault(i =>
728+
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRefactoringPreviewProvider<>));
729+
730+
return face == null ? new[] { type } : new[] { type, face };
731+
})
732+
);
733+
}
734+
718735
private void RegisterRefactoringDialogs(IWindsorContainer container)
719736
{
720737
container.Register(Types

Rubberduck.Parsing/Annotations/Concrete/FolderAnnotation.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using Rubberduck.VBEditor;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using Rubberduck.Parsing.Grammar;
5-
6-
namespace Rubberduck.Parsing.Annotations
1+
namespace Rubberduck.Parsing.Annotations
72
{
83
/// <summary>
94
/// Used for specifying the Code Explorer folder a appears under.

Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Rubberduck.Parsing.Annotations;
22
using Rubberduck.Parsing.ComReflection;
3-
using Rubberduck.Parsing.VBA;
43
using Rubberduck.VBEditor;
54
using System;
65
using System.Collections.Concurrent;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Rubberduck.Parsing.Rewriter;
2+
using Rubberduck.Parsing.VBA.Parsing;
3+
using Rubberduck.Refactorings.Exceptions;
4+
5+
namespace Rubberduck.Refactorings
6+
{
7+
public abstract class CodeOnlyRefactoringActionBase<TModel> : ICodeOnlyRefactoringAction<TModel>
8+
where TModel : class, IRefactoringModel
9+
{
10+
private readonly IRewritingManager _rewritingManager;
11+
12+
protected CodeOnlyRefactoringActionBase(IRewritingManager rewritingManager)
13+
{
14+
_rewritingManager = rewritingManager;
15+
}
16+
17+
public abstract void Refactor(TModel model, IRewriteSession rewriteSession);
18+
19+
public virtual void Refactor(TModel model)
20+
{
21+
var rewriteSession = RewriteSession(RewriteSessionCodeKind);
22+
23+
Refactor(model, rewriteSession);
24+
25+
if (!rewriteSession.TryRewrite())
26+
{
27+
throw new RewriteFailedException(rewriteSession);
28+
}
29+
}
30+
31+
private IExecutableRewriteSession RewriteSession(CodeKind codeKind)
32+
{
33+
return codeKind == CodeKind.AttributesCode
34+
? _rewritingManager.CheckOutAttributesSession()
35+
: _rewritingManager.CheckOutCodePaneSession();
36+
}
37+
38+
protected virtual CodeKind RewriteSessionCodeKind => CodeKind.CodePaneCode;
39+
}
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Rubberduck.Parsing.Rewriter;
2+
3+
namespace Rubberduck.Refactorings
4+
{
5+
/// <summary>
6+
/// The heart of a refactoring: this part of the refactoring performs the actual transformation of the code once all necessary information has been gathered.
7+
/// </summary>
8+
/// <typeparam name="TModel">The model used by the refactoring containing all information needed to specify what to do.</typeparam>
9+
public interface IRefactoringAction<in TModel> where TModel : class, IRefactoringModel
10+
{
11+
/// <summary>
12+
/// Performs the actual refactoring based on the parameters specified in the model.
13+
/// </summary>
14+
/// <param name="model">The model specifying all parameters of the refactoring</param>
15+
void Refactor(TModel model);
16+
}
17+
18+
public interface IRefactoringPreviewProvider<in TModel>
19+
where TModel : class, IRefactoringModel
20+
{
21+
/// <summary>
22+
/// Returns some preview of the refactored code.
23+
/// </summary>
24+
/// <param name="model">The model used by the refactoring containing all information needed to specify what to do.</param>
25+
/// <returns>Preview of the refactored code</returns>
26+
string Preview(TModel model);
27+
}
28+
29+
public interface ICodeOnlyRefactoringAction<in TModel> : IRefactoringAction<TModel>
30+
where TModel : class, IRefactoringModel
31+
{
32+
/// <summary>
33+
/// Performs the refactoring according to the model and using the provided rewrite session.
34+
/// </summary>
35+
/// <param name="model">The model specifying all parameters of the refactoring</param>
36+
/// <param name="rewriteSession">Rewrite session used to manipulate the code (Does not get executed.)</param>
37+
void Refactor(TModel model, IRewriteSession rewriteSession);
38+
}
39+
}

Rubberduck.Refactorings/InteractiveRefactoringBase.cs renamed to Rubberduck.Refactorings/Abstract/InteractiveRefactoringBase.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Rubberduck.Parsing.Rewriter;
2-
using Rubberduck.VBEditor.Utility;
1+
using Rubberduck.VBEditor.Utility;
32
using System;
43
using Rubberduck.Parsing.Symbols;
54
using Rubberduck.Parsing.UIContext;
@@ -13,12 +12,11 @@ public abstract class InteractiveRefactoringBase<TPresenter, TModel> : Refactori
1312
{
1413
private readonly Func<TModel, IDisposalActionContainer<TPresenter>> _presenterFactory;
1514

16-
protected InteractiveRefactoringBase(
17-
IRewritingManager rewritingManager,
15+
protected InteractiveRefactoringBase(
1816
ISelectionProvider selectionProvider,
1917
IRefactoringPresenterFactory factory,
2018
IUiDispatcher uiDispatcher)
21-
:base(rewritingManager, selectionProvider)
19+
:base(selectionProvider)
2220
{
2321
Action<TPresenter> presenterDisposalAction = (TPresenter presenter) => uiDispatcher.Invoke(() => factory.Release(presenter));
2422
_presenterFactory = ((model) => DisposalActionContainer.Create(factory.Create<TPresenter, TModel>(model), presenterDisposalAction));
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Rubberduck.Parsing.Rewriter;
2+
using Rubberduck.Parsing.VBA.Parsing;
3+
using Rubberduck.Refactorings.Exceptions;
4+
5+
namespace Rubberduck.Refactorings
6+
{
7+
public abstract class RefactoringActionBase<TModel> : IRefactoringAction<TModel>
8+
where TModel : class, IRefactoringModel
9+
{
10+
private readonly IRewritingManager _rewritingManager;
11+
12+
protected RefactoringActionBase(IRewritingManager rewritingManager)
13+
{
14+
_rewritingManager = rewritingManager;
15+
}
16+
17+
protected abstract void Refactor(TModel model, IRewriteSession rewriteSession);
18+
19+
public virtual void Refactor(TModel model)
20+
{
21+
var rewriteSession = RewriteSession(RewriteSessionCodeKind);
22+
23+
Refactor(model, rewriteSession);
24+
25+
if (!rewriteSession.TryRewrite())
26+
{
27+
throw new RewriteFailedException(rewriteSession);
28+
}
29+
}
30+
31+
private IExecutableRewriteSession RewriteSession(CodeKind codeKind)
32+
{
33+
return codeKind == CodeKind.AttributesCode
34+
? _rewritingManager.CheckOutAttributesSession()
35+
: _rewritingManager.CheckOutCodePaneSession();
36+
}
37+
38+
protected virtual CodeKind RewriteSessionCodeKind => CodeKind.CodePaneCode;
39+
}
40+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Runtime.ExceptionServices;
2+
using NLog;
3+
using Rubberduck.Parsing.Rewriter;
4+
using Rubberduck.Parsing.VBA;
5+
using Rubberduck.Refactorings.Exceptions;
6+
7+
namespace Rubberduck.Refactorings
8+
{
9+
public abstract class RefactoringActionWithSuspension<TModel> : RefactoringActionBase<TModel>
10+
where TModel : class, IRefactoringModel
11+
{
12+
private readonly IParseManager _parseManager;
13+
14+
private readonly Logger _logger;
15+
16+
protected RefactoringActionWithSuspension(IParseManager parseManager, IRewritingManager rewritingManager)
17+
: base(rewritingManager)
18+
{
19+
_parseManager = parseManager;
20+
_logger = LogManager.GetLogger(GetType().FullName);
21+
}
22+
23+
protected abstract bool RequiresSuspension(TModel model);
24+
25+
public override void Refactor(TModel model)
26+
{
27+
if (RequiresSuspension(model))
28+
{
29+
RefactorWithSuspendedParser(model);
30+
}
31+
else
32+
{
33+
base.Refactor(model);
34+
}
35+
}
36+
37+
private void RefactorWithSuspendedParser(TModel model)
38+
{
39+
var suspendResult = _parseManager.OnSuspendParser(this, new[] { ParserState.Ready }, () => base.Refactor(model));
40+
var suspendOutcome = suspendResult.Outcome;
41+
if (suspendOutcome != SuspensionOutcome.Completed)
42+
{
43+
if ((suspendOutcome == SuspensionOutcome.UnexpectedError || suspendOutcome == SuspensionOutcome.Canceled)
44+
&& suspendResult.EncounteredException != null)
45+
{
46+
ExceptionDispatchInfo.Capture(suspendResult.EncounteredException).Throw();
47+
return;
48+
}
49+
50+
_logger.Warn($"{GetType().Name} failed because a parser suspension request could not be fulfilled. The request's result was '{suspendResult.ToString()}'.");
51+
throw new SuspendParserFailureException();
52+
}
53+
}
54+
}
55+
}

Rubberduck.Refactorings/RefactoringBase.cs renamed to Rubberduck.Refactorings/Abstract/RefactoringBase.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Rubberduck.Parsing.Rewriter;
2-
using Rubberduck.Parsing.Symbols;
1+
using Rubberduck.Parsing.Symbols;
32
using Rubberduck.Refactorings.Exceptions;
43
using Rubberduck.VBEditor;
54
using Rubberduck.VBEditor.Utility;
@@ -8,12 +7,10 @@ namespace Rubberduck.Refactorings
87
{
98
public abstract class RefactoringBase : IRefactoring
109
{
11-
protected readonly IRewritingManager RewritingManager;
1210
protected readonly ISelectionProvider SelectionProvider;
1311

14-
protected RefactoringBase(IRewritingManager rewritingManager, ISelectionProvider selectionProvider)
12+
protected RefactoringBase(ISelectionProvider selectionProvider)
1513
{
16-
RewritingManager = rewritingManager;
1714
SelectionProvider = selectionProvider;
1815
}
1916

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Rubberduck.Parsing.Rewriter;
2+
using Rubberduck.Parsing.VBA.Parsing;
3+
using Rubberduck.VBEditor;
4+
5+
namespace Rubberduck.Refactorings
6+
{
7+
public abstract class RefactoringPreviewProviderWrapperBase<TModel> : IRefactoringPreviewProvider<TModel>
8+
where TModel : class, IRefactoringModel
9+
{
10+
private readonly IRewritingManager _rewritingManager;
11+
private readonly ICodeOnlyRefactoringAction<TModel> _refactoringAction;
12+
13+
protected RefactoringPreviewProviderWrapperBase(
14+
ICodeOnlyRefactoringAction<TModel> refactoringAction,
15+
IRewritingManager rewritingManager)
16+
{
17+
_refactoringAction = refactoringAction;
18+
_rewritingManager = rewritingManager;
19+
}
20+
21+
protected abstract QualifiedModuleName ComponentToShow(TModel model);
22+
23+
public string Preview(TModel model)
24+
{
25+
var rewriteSession = RewriteSession(RewriteSessionCodeKind);
26+
_refactoringAction.Refactor(model, rewriteSession);
27+
var componentToShow = ComponentToShow(model);
28+
var rewriter = rewriteSession.CheckOutModuleRewriter(componentToShow);
29+
return rewriter.GetText();
30+
}
31+
32+
private IExecutableRewriteSession RewriteSession(CodeKind codeKind)
33+
{
34+
return codeKind == CodeKind.AttributesCode
35+
? _rewritingManager.CheckOutAttributesSession()
36+
: _rewritingManager.CheckOutCodePaneSession();
37+
}
38+
39+
protected virtual CodeKind RewriteSessionCodeKind => CodeKind.CodePaneCode;
40+
}
41+
}

Rubberduck.Refactorings/EncapsulateField/EncapsulateFieldModel.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Linq;
54
using Rubberduck.Parsing.Symbols;
65
using Rubberduck.Parsing.VBA;
7-
using Rubberduck.Refactorings.EncapsulateField.Extensions;
86
using Rubberduck.VBEditor;
97

108
namespace Rubberduck.Refactorings.EncapsulateField

0 commit comments

Comments
 (0)