Skip to content

Commit df01e8a

Browse files
authored
Merge pull request #5555 from BZngr/EncapsulateField_ClearBlanklines
Clean-up blank lines left behind by EncapsulateFieldRefactoring and MoveCloserToUsage
2 parents d5a5587 + 61795ef commit df01e8a

File tree

12 files changed

+446
-199
lines changed

12 files changed

+446
-199
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using Antlr4.Runtime;
2+
using Rubberduck.Parsing;
3+
using Rubberduck.Parsing.Grammar;
4+
using Rubberduck.Parsing.Rewriter;
5+
using Rubberduck.Parsing.Symbols;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
10+
namespace Rubberduck.Refactorings.Common
11+
{
12+
public static class IModuleRewriterExtensions
13+
{
14+
/// <summary>
15+
/// Removes variable declaration and subsequent <c>VBAParser.EndOfStatementContext</c>
16+
/// depending on the <paramref name="removeEndOfStmtContext"/> flag.
17+
/// This function is intended to be called only once per rewriter within a given <c>ModuleRewriteSession</c>.
18+
/// </summary>
19+
/// <remarks>
20+
/// Calling this function with <paramref name="removeEndOfStmtContext"/> defaulted to <c>true</c>
21+
/// avoids leaving residual newlines between the deleted declaration and the next declaration.
22+
/// The one-time call constraint is required for scenarios where variables to delete are declared in a list. Specifically,
23+
/// the use case where all the variables in the list are to be removed.
24+
/// If the variables to remove are not declared in a list, then this function can be called multiple times.
25+
/// </remarks>
26+
public static void RemoveVariables(this IModuleRewriter rewriter, IEnumerable<VariableDeclaration> toRemove, bool removeEndOfStmtContext = true)
27+
{
28+
if (!toRemove.Any())
29+
{
30+
return;
31+
}
32+
33+
var fieldsToDeleteByListContext = toRemove.Distinct()
34+
.ToLookup(f => f.Context.GetAncestor<VBAParser.VariableListStmtContext>());
35+
36+
foreach (var fieldsToDelete in fieldsToDeleteByListContext)
37+
{
38+
var variableList = fieldsToDelete.Key.children.OfType<VBAParser.VariableSubStmtContext>();
39+
40+
if (variableList.Count() == fieldsToDelete.Count())
41+
{
42+
if (fieldsToDelete.First().ParentDeclaration.DeclarationType.HasFlag(DeclarationType.Module))
43+
{
44+
rewriter.RemoveDeclarationContext<VBAParser.ModuleDeclarationsElementContext>(fieldsToDelete.First(), removeEndOfStmtContext);
45+
}
46+
else
47+
{
48+
rewriter.RemoveDeclarationContext<VBAParser.BlockStmtContext>(fieldsToDelete.First(), removeEndOfStmtContext);
49+
}
50+
continue;
51+
}
52+
53+
foreach (var target in fieldsToDelete)
54+
{
55+
rewriter.Remove(target);
56+
}
57+
}
58+
}
59+
60+
/// <summary>
61+
/// Removes a member declaration and subsequent <c>VBAParser.EndOfStatementContext</c>
62+
/// depending on the <paramref name="removeEndOfStmtContext"/> flag.
63+
/// </summary>
64+
/// <remarks>
65+
/// Calling this function with <paramref name="removeEndOfStmtContext"/> defaulted to <c>true</c>
66+
/// avoids leaving residual newlines between the deleted declaration and the next declaration.
67+
/// </remarks>
68+
public static void RemoveMember(this IModuleRewriter rewriter, ModuleBodyElementDeclaration target, bool removeEndOfStmtContext = true)
69+
{
70+
RemoveMembers(rewriter, new ModuleBodyElementDeclaration[] { target }, removeEndOfStmtContext);
71+
}
72+
73+
/// <summary>
74+
/// Removes member declarations and subsequent <c>VBAParser.EndOfStatementContext</c>
75+
/// depending on the <paramref name="removeEndOfStmtContext"/> flag.
76+
/// </summary>
77+
/// <remarks>
78+
/// Calling this function with <paramref name="removeEndOfStmtContext"/> defaulted to <c>true</c>
79+
/// avoids leaving residual newlines between the deleted declaration and the next declaration.
80+
/// </remarks>
81+
public static void RemoveMembers(this IModuleRewriter rewriter, IEnumerable<ModuleBodyElementDeclaration> toRemove, bool removeEndOfStmtContext = true)
82+
{
83+
if (!toRemove.Any())
84+
{
85+
return;
86+
}
87+
88+
foreach (var member in toRemove)
89+
{
90+
rewriter.RemoveDeclarationContext<VBAParser.ModuleBodyElementContext>(member, removeEndOfStmtContext);
91+
}
92+
}
93+
94+
private static void RemoveDeclarationContext<T>(this IModuleRewriter rewriter, Declaration declaration, bool removeEndOfStmtContext = true) where T : ParserRuleContext
95+
{
96+
if (!declaration.Context.TryGetAncestor<T>(out var elementContext))
97+
{
98+
throw new ArgumentException();
99+
}
100+
101+
rewriter.Remove(elementContext);
102+
if (removeEndOfStmtContext && elementContext.TryGetFollowingContext<VBAParser.EndOfStatementContext>(out var nextContext))
103+
{
104+
rewriter.Remove(nextContext);
105+
}
106+
}
107+
}
108+
}

Rubberduck.Refactorings/EncapsulateField/EncapsulateFieldRefactoring.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Rubberduck.VBEditor;
77
using Rubberduck.SmartIndenter;
88
using Rubberduck.VBEditor.Utility;
9-
using System;
109

1110
namespace Rubberduck.Refactorings.EncapsulateField
1211
{
@@ -91,26 +90,25 @@ protected override EncapsulateFieldModel InitializeModel(Declaration target)
9190

9291
protected override void RefactorImpl(EncapsulateFieldModel model)
9392
{
94-
var refactorRewriteSession = new EncapsulateFieldRewriteSession(_rewritingManager.CheckOutCodePaneSession()) as IEncapsulateFieldRewriteSession;
93+
var executableRewriteSession = _rewritingManager.CheckOutCodePaneSession();
9594

96-
refactorRewriteSession = RefactorRewrite(model, refactorRewriteSession);
95+
RefactorRewrite(model, executableRewriteSession);
9796

98-
if (!refactorRewriteSession.TryRewrite())
97+
if (!executableRewriteSession.TryRewrite())
9998
{
100-
throw new RewriteFailedException(refactorRewriteSession.RewriteSession);
99+
throw new RewriteFailedException(executableRewriteSession);
101100
}
102101
}
103102

104103
private string PreviewRewrite(EncapsulateFieldModel model)
105104
{
106-
var previewSession = new EncapsulateFieldRewriteSession(_rewritingManager.CheckOutCodePaneSession()) as IEncapsulateFieldRewriteSession; ;
105+
var previewSession = RefactorRewrite(model, _rewritingManager.CheckOutCodePaneSession(), true);
107106

108-
previewSession = RefactorRewrite(model, previewSession, true);
109-
110-
return previewSession.CreatePreview(model.QualifiedModuleName);
107+
return previewSession.CheckOutModuleRewriter(model.QualifiedModuleName)
108+
.GetText();
111109
}
112110

113-
private IEncapsulateFieldRewriteSession RefactorRewrite(EncapsulateFieldModel model, IEncapsulateFieldRewriteSession refactorRewriteSession, bool asPreview = false)
111+
private IRewriteSession RefactorRewrite(EncapsulateFieldModel model, IRewriteSession refactorRewriteSession, bool asPreview = false)
114112
{
115113
if (!model.SelectedFieldCandidates.Any()) { return refactorRewriteSession; }
116114

Rubberduck.Refactorings/EncapsulateField/EncapsulateFieldRewriteSession.cs

Lines changed: 0 additions & 98 deletions
This file was deleted.

Rubberduck.Refactorings/EncapsulateField/EncapsulationStrategies/ConvertFieldsToUDTMembers.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
using Antlr4.Runtime;
2-
using Rubberduck.Parsing.Grammar;
3-
using Rubberduck.Parsing.Rewriter;
1+
using Rubberduck.Parsing.Rewriter;
42
using Rubberduck.Parsing.Symbols;
53
using Rubberduck.Parsing.VBA;
64
using Rubberduck.Refactorings.Common;
7-
using Rubberduck.Refactorings.EncapsulateField.Extensions;
85
using Rubberduck.SmartIndenter;
9-
using Rubberduck.VBEditor;
10-
using System;
11-
using System.Collections.Generic;
126
using System.Diagnostics;
13-
using System.IO;
147
using System.Linq;
15-
using System.Text;
16-
using System.Threading.Tasks;
178

189
namespace Rubberduck.Refactorings.EncapsulateField
1910
{
@@ -27,14 +18,12 @@ public ConvertFieldsToUDTMembers(IDeclarationFinderProvider declarationFinderPro
2718
_stateUDTField = model.ObjectStateUDTField;
2819
}
2920

30-
protected override void ModifyFields(IEncapsulateFieldRewriteSession refactorRewriteSession)
21+
protected override void ModifyFields(IRewriteSession refactorRewriteSession)
3122
{
3223
var rewriter = refactorRewriteSession.CheckOutModuleRewriter(_targetQMN);
3324

34-
foreach (var field in SelectedFields)
35-
{
36-
refactorRewriteSession.Remove(field.Declaration, rewriter);
37-
}
25+
rewriter.RemoveVariables(SelectedFields.Select(f => f.Declaration)
26+
.Cast<VariableDeclaration>());
3827

3928
if (_stateUDTField.IsExistingDeclaration)
4029
{
@@ -44,7 +33,7 @@ protected override void ModifyFields(IEncapsulateFieldRewriteSession refactorRew
4433
}
4534
}
4635

47-
protected override void ModifyReferences(IEncapsulateFieldRewriteSession refactorRewriteSession)
36+
protected override void ModifyReferences(IRewriteSession refactorRewriteSession)
4837
{
4938
foreach (var field in SelectedFields)
5039
{

Rubberduck.Refactorings/EncapsulateField/EncapsulationStrategies/EncapsulateFieldStrategyBase.cs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Antlr4.Runtime;
22
using Rubberduck.Parsing;
33
using Rubberduck.Parsing.Grammar;
4+
using Rubberduck.Parsing.Rewriter;
45
using Rubberduck.Parsing.Symbols;
56
using Rubberduck.Parsing.VBA;
67
using Rubberduck.Refactorings.Common;
@@ -12,8 +13,6 @@
1213
using System.Collections.Generic;
1314
using System.Diagnostics;
1415
using System.Linq;
15-
using System.Text;
16-
using System.Threading.Tasks;
1716

1817
namespace Rubberduck.Refactorings.EncapsulateField
1918
{
@@ -33,7 +32,7 @@ public struct PropertyAttributeSet
3332

3433
public interface IEncapsulateStrategy
3534
{
36-
IEncapsulateFieldRewriteSession RefactorRewrite(IEncapsulateFieldRewriteSession refactorRewriteSession, bool asPreview);
35+
IRewriteSession RefactorRewrite(IRewriteSession refactorRewriteSession, bool asPreview);
3736
}
3837

3938
public abstract class EncapsulateFieldStrategyBase : IEncapsulateStrategy
@@ -57,15 +56,15 @@ public EncapsulateFieldStrategyBase(IDeclarationFinderProvider declarationFinder
5756
_targetQMN = model.QualifiedModuleName;
5857
_indenter = indenter;
5958
_codeBuilder = codeBuilder;
60-
SelectedFields = model.SelectedFieldCandidates;
59+
SelectedFields = model.SelectedFieldCandidates.ToList();
6160

6261
_codeSectionStartIndex = declarationFinderProvider.DeclarationFinder
6362
.Members(_targetQMN).Where(m => m.IsMember())
6463
.OrderBy(c => c.Selection)
6564
.FirstOrDefault()?.Context.Start.TokenIndex ?? null;
6665
}
6766

68-
public IEncapsulateFieldRewriteSession RefactorRewrite(IEncapsulateFieldRewriteSession refactorRewriteSession, bool asPreview)
67+
public IRewriteSession RefactorRewrite(IRewriteSession refactorRewriteSession, bool asPreview)
6968
{
7069
ModifyFields(refactorRewriteSession);
7170

@@ -76,13 +75,13 @@ public IEncapsulateFieldRewriteSession RefactorRewrite(IEncapsulateFieldRewriteS
7675
return refactorRewriteSession;
7776
}
7877

79-
protected abstract void ModifyFields(IEncapsulateFieldRewriteSession rewriteSession);
78+
protected abstract void ModifyFields(IRewriteSession rewriteSession);
8079

81-
protected abstract void ModifyReferences(IEncapsulateFieldRewriteSession refactorRewriteSession);
80+
protected abstract void ModifyReferences(IRewriteSession refactorRewriteSession);
8281

8382
protected abstract void LoadNewDeclarationBlocks();
8483

85-
protected void RewriteReferences(IEncapsulateFieldRewriteSession refactorRewriteSession)
84+
protected void RewriteReferences(IRewriteSession refactorRewriteSession)
8685
{
8786
foreach (var replacement in IdentifierReplacements)
8887
{
@@ -95,7 +94,7 @@ protected void RewriteReferences(IEncapsulateFieldRewriteSession refactorRewrite
9594
protected void AddContentBlock(NewContentTypes contentType, string block)
9695
=> _newContent[contentType].Add(block);
9796

98-
private void InsertNewContent(IEncapsulateFieldRewriteSession refactorRewriteSession, bool isPreview = false)
97+
private void InsertNewContent(IRewriteSession refactorRewriteSession, bool isPreview = false)
9998
{
10099
_newContent = new Dictionary<NewContentTypes, List<string>>
101100
{
@@ -119,16 +118,8 @@ private void InsertNewContent(IEncapsulateFieldRewriteSession refactorRewriteSes
119118
.Concat(_newContent[NewContentTypes.DeclarationBlock])
120119
.Concat(_newContent[NewContentTypes.MethodBlock])
121120
.Concat(_newContent[NewContentTypes.PostContentMessage]))
122-
.Trim();
123-
124-
var maxConsecutiveNewLines = 3;
125-
var target = string.Join(string.Empty, Enumerable.Repeat(Environment.NewLine, maxConsecutiveNewLines).ToList());
126-
var replacement = string.Join(string.Empty, Enumerable.Repeat(Environment.NewLine, maxConsecutiveNewLines - 1).ToList());
127-
for (var counter = 1; counter < 10 && newContentBlock.Contains(target); counter++)
128-
{
129-
newContentBlock = newContentBlock.Replace(target, replacement);
130-
}
131-
121+
.Trim()
122+
.LimitNewlines();
132123

133124
var rewriter = refactorRewriteSession.CheckOutModuleRewriter(_targetQMN);
134125
if (_codeSectionStartIndex.HasValue)

0 commit comments

Comments
 (0)