Skip to content

Commit 33a3bd0

Browse files
committed
streamlined removal of unused constant, variable and procedure
1 parent 43d1397 commit 33a3bd0

12 files changed

+234
-184
lines changed

RetailCoder.VBE/Common/CodeModuleExtensions.cs

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,166 @@
1-
using Antlr4.Runtime;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Antlr4.Runtime;
5+
using Rubberduck.Parsing;
26
using Rubberduck.Parsing.Symbols;
7+
using Rubberduck.Parsing.VBA;
8+
using Rubberduck.VBEditor;
39
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
410

511
namespace Rubberduck.Common
612
{
713
public static class CodeModuleExtensions
814
{
15+
/// <summary>
16+
/// Removes a <see cref="Declaration"/> and its <see cref="Declaration.References"/>.
17+
/// </summary>
18+
/// <param name="module">The <see cref="ICodeModule"/> to modify.</param>
19+
/// <param name="target"></param>
20+
public static void Remove(this ICodeModule module, Declaration target)
21+
{
22+
var multipleDeclarations = target.DeclarationType == DeclarationType.Variable && target.HasMultipleDeclarationsInStatement();
23+
var context = GetStmtContext(target);
24+
var declarationText = context.GetText().Replace(" _" + Environment.NewLine, string.Empty);
25+
var selection = GetStmtContextSelection(target);
26+
27+
var oldLines = module.GetLines(selection);
28+
29+
var newLines = oldLines.Replace(" _" + Environment.NewLine, string.Empty)
30+
.Remove(selection.StartColumn - 1, declarationText.Length);
31+
32+
if (multipleDeclarations)
33+
{
34+
selection = GetStmtContextSelection(target);
35+
newLines = RemoveExtraComma(module.GetLines(selection).Replace(oldLines, newLines),
36+
target.CountOfDeclarationsInStatement(), target.IndexOfVariableDeclarationInStatement());
37+
}
38+
39+
var newLinesWithoutExcessSpaces = newLines.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
40+
for (var i = 0; i < newLinesWithoutExcessSpaces.Length; i++)
41+
{
42+
newLinesWithoutExcessSpaces[i] = newLinesWithoutExcessSpaces[i].RemoveExtraSpacesLeavingIndentation();
43+
}
44+
45+
for (var i = newLinesWithoutExcessSpaces.Length - 1; i >= 0; i--)
46+
{
47+
if (newLinesWithoutExcessSpaces[i].Trim() == string.Empty)
48+
{
49+
continue;
50+
}
51+
52+
if (newLinesWithoutExcessSpaces[i].EndsWith(" _"))
53+
{
54+
newLinesWithoutExcessSpaces[i] =
55+
newLinesWithoutExcessSpaces[i].Remove(newLinesWithoutExcessSpaces[i].Length - 2);
56+
}
57+
break;
58+
}
59+
60+
// remove all lines with only whitespace
61+
newLinesWithoutExcessSpaces = newLinesWithoutExcessSpaces.Where(str => str.Any(c => !char.IsWhiteSpace(c))).ToArray();
62+
63+
module.DeleteLines(selection);
64+
if (newLinesWithoutExcessSpaces.Any())
65+
{
66+
module.InsertLines(selection.StartLine, string.Join(Environment.NewLine, newLinesWithoutExcessSpaces));
67+
}
68+
}
69+
70+
private static Selection GetStmtContextSelection(Declaration target)
71+
{
72+
switch (target.DeclarationType)
73+
{
74+
case DeclarationType.Variable:
75+
return target.GetVariableStmtContextSelection();
76+
case DeclarationType.Constant:
77+
return target.GetConstStmtContextSelection();
78+
default:
79+
return target.Context.GetSelection();
80+
}
81+
}
82+
83+
private static ParserRuleContext GetStmtContext(Declaration target)
84+
{
85+
switch (target.DeclarationType)
86+
{
87+
case DeclarationType.Variable:
88+
return target.GetVariableStmtContext();
89+
case DeclarationType.Constant:
90+
return target.GetConstStmtContext();
91+
default:
92+
return target.Context;
93+
}
94+
}
95+
96+
private static string RemoveExtraComma(string str, int numParams, int indexRemoved)
97+
{
98+
#region usage example
99+
// Example use cases for this method (fields and variables):
100+
// Dim fizz as Boolean, dizz as Double
101+
// Private fizz as Boolean, dizz as Double
102+
// Public fizz as Boolean, _
103+
// dizz as Double
104+
// Private fizz as Boolean _
105+
// , dizz as Double _
106+
// , iizz as Integer
107+
108+
// Before this method is called, the parameter to be removed has
109+
// already been removed. This means 'str' will look like:
110+
// Dim fizz as Boolean,
111+
// Private , dizz as Double
112+
// Public fizz as Boolean, _
113+
//
114+
// Private _
115+
// , dizz as Double _
116+
// , iizz as Integer
117+
118+
// This method is responsible for removing the redundant comma
119+
// and returning a string similar to:
120+
// Dim fizz as Boolean
121+
// Private dizz as Double
122+
// Public fizz as Boolean _
123+
//
124+
// Private _
125+
// dizz as Double _
126+
// , iizz as Integer
127+
#endregion
128+
var commaToRemove = numParams == indexRemoved ? indexRemoved - 1 : indexRemoved;
129+
return str.Remove(str.NthIndexOf(',', commaToRemove), 1);
130+
}
131+
132+
public static void Remove(this ICodeModule module, ConstantDeclaration target)
133+
{
134+
135+
}
136+
137+
public static void Remove(this ICodeModule module, IdentifierReference target)
138+
{
139+
var parent = target.Context.Parent as ParserRuleContext;
140+
module.Remove(parent.GetSelection(), parent);
141+
}
142+
143+
public static void Remove(this ICodeModule module, IEnumerable<IdentifierReference> targets)
144+
{
145+
foreach (var target in targets.OrderByDescending(e => e.Selection))
146+
{
147+
module.Remove(target);
148+
}
149+
}
150+
151+
public static void Remove(this ICodeModule module, Selection selection, ParserRuleContext instruction)
152+
{
153+
var originalCodeLines = module.GetLines(selection.StartLine, selection.LineCount);
154+
var originalInstruction = instruction.GetText();
155+
module.DeleteLines(selection.StartLine, selection.LineCount);
156+
157+
var newCodeLines = originalCodeLines.Replace(originalInstruction, string.Empty);
158+
if (!string.IsNullOrEmpty(newCodeLines))
159+
{
160+
module.InsertLines(selection.StartLine, newCodeLines);
161+
}
162+
}
163+
9164
public static void ReplaceToken(this ICodeModule module, IToken token, string replacement)
10165
{
11166
var original = module.GetLines(token.Line, 1);
@@ -22,13 +177,14 @@ public static void ReplaceIdentifierReferenceName(this ICodeModule module, Ident
22177

23178
public static void InsertLines(this ICodeModule module, int startLine, string[] lines)
24179
{
25-
int lineNumber = startLine;
26-
for ( int idx = 0; idx < lines.Length; idx++ )
180+
var lineNumber = startLine;
181+
for (var idx = 0; idx < lines.Length; idx++)
27182
{
28183
module.InsertLines(lineNumber, lines[idx]);
29184
lineNumber++;
30185
}
31186
}
187+
32188
private static string ReplaceStringAtIndex(string original, string toReplace, string replacement, int startIndex)
33189
{
34190
var modifiedContent = original.Remove(startIndex, toReplace.Length);

RetailCoder.VBE/Inspections/ConstantNotUsedInspection.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
using Rubberduck.Inspections.Results;
66
using Rubberduck.Parsing.Symbols;
77
using Rubberduck.Parsing.VBA;
8+
using Rubberduck.UI;
89

910
namespace Rubberduck.Inspections
1011
{
1112
public sealed class ConstantNotUsedInspection : InspectionBase
1213
{
13-
public ConstantNotUsedInspection(RubberduckParserState state)
14+
private readonly IMessageBox _messageBox;
15+
16+
public ConstantNotUsedInspection(RubberduckParserState state, IMessageBox messageBox)
1417
: base(state)
1518
{
19+
_messageBox = messageBox;
1620
}
1721

1822
public override string Meta { get { return InspectionsUI.ConstantNotUsedInspectionMeta; } }

RetailCoder.VBE/Inspections/ParameterNotUsedInspection.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Collections.Generic;
22
using System.Linq;
3-
using Rubberduck.Common;
43
using Rubberduck.Inspections.Abstract;
54
using Rubberduck.Inspections.Resources;
65
using Rubberduck.Inspections.Results;

RetailCoder.VBE/Inspections/ProcedureNotUsedInspection.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66
using Rubberduck.Inspections.Results;
77
using Rubberduck.Parsing.Symbols;
88
using Rubberduck.Parsing.VBA;
9+
using Rubberduck.UI;
910
using Rubberduck.VBEditor.SafeComWrappers;
1011

1112
namespace Rubberduck.Inspections
1213
{
1314
public sealed class ProcedureNotUsedInspection : InspectionBase
1415
{
15-
public ProcedureNotUsedInspection(RubberduckParserState state)
16+
private readonly IMessageBox _messageBox;
17+
18+
public ProcedureNotUsedInspection(RubberduckParserState state, IMessageBox messageBox)
1619
: base(state)
1720
{
21+
_messageBox = messageBox;
1822
}
1923

2024
public override string Meta { get { return InspectionsUI.ProcedureNotUsedInspectionMeta; } }
Lines changed: 6 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System;
2-
using System.Linq;
31
using Antlr4.Runtime;
42
using Rubberduck.Common;
53
using Rubberduck.Inspections.Abstract;
64
using Rubberduck.Inspections.Resources;
75
using Rubberduck.Parsing.Symbols;
8-
using Rubberduck.Parsing.VBA;
96
using Rubberduck.VBEditor;
107

118
namespace Rubberduck.Inspections.QuickFixes
@@ -25,140 +22,13 @@ public RemoveUnusedDeclarationQuickFix(ParserRuleContext context, QualifiedSelec
2522

2623
public override void Fix()
2724
{
28-
if (_target.DeclarationType == DeclarationType.Variable || _target.DeclarationType == DeclarationType.Constant)
29-
{
30-
RemoveVariable(_target);
31-
}
32-
else
33-
{
34-
var module = Selection.QualifiedName.Component.CodeModule;
35-
{
36-
var selection = Selection.Selection;
37-
var originalCodeLines = module.GetLines(selection.StartLine, selection.LineCount);
25+
var module = _target
26+
.QualifiedName
27+
.QualifiedModuleName
28+
.Component
29+
.CodeModule;
3830

39-
var originalInstruction = Context.GetText();
40-
module.DeleteLines(selection.StartLine, selection.LineCount);
41-
42-
var newCodeLines = originalCodeLines.Replace(originalInstruction, string.Empty);
43-
if (!string.IsNullOrEmpty(newCodeLines))
44-
{
45-
module.InsertLines(selection.StartLine, newCodeLines);
46-
}
47-
}
48-
}
49-
}
50-
51-
private void RemoveVariable(Declaration target)
52-
{
53-
Selection selection;
54-
var declarationText = target.Context.GetText().Replace(" _" + Environment.NewLine, string.Empty);
55-
var multipleDeclarations = target.DeclarationType == DeclarationType.Variable && target.HasMultipleDeclarationsInStatement();
56-
57-
if (!multipleDeclarations)
58-
{
59-
declarationText = GetStmtContext(target).GetText().Replace(" _" + Environment.NewLine, string.Empty);
60-
selection = GetStmtContextSelection(target);
61-
}
62-
else
63-
{
64-
selection = new Selection(target.Context.Start.Line, target.Context.Start.Column,
65-
target.Context.Stop.Line, target.Context.Stop.Column);
66-
}
67-
68-
var module = target.QualifiedName.QualifiedModuleName.Component.CodeModule;
69-
{
70-
var oldLines = module.GetLines(selection);
71-
72-
var newLines = oldLines.Replace(" _" + Environment.NewLine, string.Empty)
73-
.Remove(selection.StartColumn, declarationText.Length);
74-
75-
if (multipleDeclarations)
76-
{
77-
selection = GetStmtContextSelection(target);
78-
newLines = RemoveExtraComma(module.GetLines(selection).Replace(oldLines, newLines),
79-
target.CountOfDeclarationsInStatement(), target.IndexOfVariableDeclarationInStatement());
80-
}
81-
82-
var newLinesWithoutExcessSpaces = newLines.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
83-
for (var i = 0; i < newLinesWithoutExcessSpaces.Length; i++)
84-
{
85-
newLinesWithoutExcessSpaces[i] = newLinesWithoutExcessSpaces[i].RemoveExtraSpacesLeavingIndentation();
86-
}
87-
88-
for (var i = newLinesWithoutExcessSpaces.Length - 1; i >= 0; i--)
89-
{
90-
if (newLinesWithoutExcessSpaces[i].Trim() == string.Empty)
91-
{
92-
continue;
93-
}
94-
95-
if (newLinesWithoutExcessSpaces[i].EndsWith(" _"))
96-
{
97-
newLinesWithoutExcessSpaces[i] =
98-
newLinesWithoutExcessSpaces[i].Remove(newLinesWithoutExcessSpaces[i].Length - 2);
99-
}
100-
break;
101-
}
102-
103-
// remove all lines with only whitespace
104-
newLinesWithoutExcessSpaces = newLinesWithoutExcessSpaces.Where(str => str.Any(c => !char.IsWhiteSpace(c))).ToArray();
105-
106-
module.DeleteLines(selection);
107-
if (newLinesWithoutExcessSpaces.Any())
108-
{
109-
module.InsertLines(selection.StartLine, string.Join(Environment.NewLine, newLinesWithoutExcessSpaces));
110-
}
111-
}
112-
}
113-
114-
private Selection GetStmtContextSelection(Declaration target)
115-
{
116-
return target.DeclarationType == DeclarationType.Variable
117-
? target.GetVariableStmtContextSelection()
118-
: target.GetConstStmtContextSelection();
119-
}
120-
121-
private ParserRuleContext GetStmtContext(Declaration target)
122-
{
123-
return target.DeclarationType == DeclarationType.Variable
124-
? (ParserRuleContext)target.GetVariableStmtContext()
125-
: (ParserRuleContext)target.GetConstStmtContext();
126-
}
127-
128-
private string RemoveExtraComma(string str, int numParams, int indexRemoved)
129-
{
130-
// Example use cases for this method (fields and variables):
131-
// Dim fizz as Boolean, dizz as Double
132-
// Private fizz as Boolean, dizz as Double
133-
// Public fizz as Boolean, _
134-
// dizz as Double
135-
// Private fizz as Boolean _
136-
// , dizz as Double _
137-
// , iizz as Integer
138-
139-
// Before this method is called, the parameter to be removed has
140-
// already been removed. This means 'str' will look like:
141-
// Dim fizz as Boolean,
142-
// Private , dizz as Double
143-
// Public fizz as Boolean, _
144-
//
145-
// Private _
146-
// , dizz as Double _
147-
// , iizz as Integer
148-
149-
// This method is responsible for removing the redundant comma
150-
// and returning a string similar to:
151-
// Dim fizz as Boolean
152-
// Private dizz as Double
153-
// Public fizz as Boolean _
154-
//
155-
// Private _
156-
// dizz as Double _
157-
// , iizz as Integer
158-
159-
var commaToRemove = numParams == indexRemoved ? indexRemoved - 1 : indexRemoved;
160-
161-
return str.Remove(str.NthIndexOf(',', commaToRemove), 1);
31+
module.Remove(_target);
16232
}
16333
}
16434
}

0 commit comments

Comments
 (0)