Skip to content

Commit 08783ee

Browse files
authored
Merge pull request #4491 from bclothier/CleanComSafeLeakRound2
Clean COM wrappers leak: Round 2
2 parents 862e722 + 599e852 commit 08783ee

File tree

28 files changed

+645
-482
lines changed

28 files changed

+645
-482
lines changed

Rubberduck.API/VBA/Parser.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ public interface IParserEvents
6767
]
6868
public sealed class Parser : IParser, IDisposable
6969
{
70-
private RubberduckParserState _state;
71-
private SynchronousParseCoordinator _parser;
72-
private IVBE _vbe;
73-
private IVBEEvents _vbeEvents;
70+
private readonly RubberduckParserState _state;
71+
private readonly SynchronousParseCoordinator _parser;
72+
private readonly IVBE _vbe;
73+
private readonly IVBEEvents _vbeEvents;
7474
private readonly IUiDispatcher _dispatcher;
7575
private readonly CancellationTokenSource _tokenSource;
7676

@@ -228,6 +228,9 @@ public void Dispose()
228228
}
229229

230230
_disposed = true;
231+
_parser?.Dispose();
232+
_vbe?.Dispose();
233+
_tokenSource.Dispose();
231234
}
232235
}
233236
}

Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio
3333

3434
int annotationLine;
3535
//TODO: Make this use the parse tree instead of the code module.
36-
var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName);
36+
using (var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName))
3737
using (var module = component.CodeModule)
3838
{
3939
annotationLine = result.QualifiedSelection.Selection.StartLine;

Rubberduck.Core/Common/ExportFormatter.cs

Lines changed: 201 additions & 194 deletions
Large diffs are not rendered by default.

Rubberduck.Core/Common/WindowsOperatingSystem.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public void ShowFolder(string folderPath)
1111
{
1212
Directory.CreateDirectory(folderPath);
1313
}
14-
Process.Start(folderPath);
14+
15+
using (Process.Start(folderPath)) { }
1516
}
1617
}
1718
}

Rubberduck.Core/UI/CodeExplorer/Commands/AddMDIFormCommand.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,17 @@ private bool EvaluateCanExecuteCore(IVBProject project, CodeExplorerItemViewMode
4545
return false;
4646
}
4747

48-
foreach (var component in project.VBComponents)
48+
using (var components = project.VBComponents)
4949
{
50-
using (component)
50+
foreach (var component in components)
5151
{
52-
if (component.Type == ComponentType.MDIForm)
52+
using (component)
5353
{
54-
// Only one MDI Form allowed per project
55-
return false;
54+
if (component.Type == ComponentType.MDIForm)
55+
{
56+
// Only one MDI Form allowed per project
57+
return false;
58+
}
5659
}
5760
}
5861
}

Rubberduck.Core/UI/CodeExplorer/Commands/CopyResultsCommand.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,31 @@ public CopyResultsCommand(RubberduckParserState state) : base(LogManager.GetCurr
2222

2323
protected override void OnExecute(object parameter)
2424
{
25-
const string XML_SPREADSHEET_DATA_FORMAT = "XML Spreadsheet";
25+
const string XML_SPREADSHEET_DATA_FORMAT = "XML Spreadsheet";
2626

27-
ColumnInfo[] ColumnInfos = { new ColumnInfo("Project"), new ColumnInfo("Folder"), new ColumnInfo("Component"), new ColumnInfo("Declaration Type"), new ColumnInfo("Scope"),
28-
new ColumnInfo("Name"), new ColumnInfo("Return Type") };
27+
ColumnInfo[] ColumnInfos = { new ColumnInfo("Project"), new ColumnInfo("Folder"), new ColumnInfo("Component"), new ColumnInfo("Declaration Type"), new ColumnInfo("Scope"),
28+
new ColumnInfo("Name"), new ColumnInfo("Return Type") };
2929

30-
// this.ProjectName, this.CustomFolder, this.ComponentName, this.DeclarationType.ToString(), this.Scope
31-
var aDeclarations = _state.AllUserDeclarations.Select(declaration => declaration.ToArray()).ToArray();
30+
// this.ProjectName, this.CustomFolder, this.ComponentName, this.DeclarationType.ToString(), this.Scope
31+
var aDeclarations = _state.AllUserDeclarations.Select(declaration => declaration.ToArray()).ToArray();
3232

33-
const string resource = "Rubberduck User Declarations - {0}";
34-
var title = string.Format(resource, DateTime.Now.ToString(CultureInfo.InvariantCulture));
35-
36-
var csvResults = ExportFormatter.Csv(aDeclarations, title, ColumnInfos);
37-
var htmlResults = ExportFormatter.HtmlClipboardFragment(aDeclarations, title, ColumnInfos);
38-
var rtfResults = ExportFormatter.RTF(aDeclarations, title);
33+
const string resource = "Rubberduck User Declarations - {0}";
34+
var title = string.Format(resource, DateTime.Now.ToString(CultureInfo.InvariantCulture));
35+
36+
var csvResults = ExportFormatter.Csv(aDeclarations, title, ColumnInfos);
37+
var htmlResults = ExportFormatter.HtmlClipboardFragment(aDeclarations, title, ColumnInfos);
38+
var rtfResults = ExportFormatter.RTF(aDeclarations, title);
3939

40-
var strm1 = ExportFormatter.XmlSpreadsheetNew(aDeclarations, title, ColumnInfos);
40+
using (var strm1 = ExportFormatter.XmlSpreadsheetNew(aDeclarations, title, ColumnInfos))
41+
{
4142
//Add the formats from richest formatting to least formatting
4243
_clipboard.AppendStream(DataFormats.GetDataFormat(XML_SPREADSHEET_DATA_FORMAT).Name, strm1);
4344
_clipboard.AppendString(DataFormats.Rtf, rtfResults);
4445
_clipboard.AppendString(DataFormats.Html, htmlResults);
4546
_clipboard.AppendString(DataFormats.CommaSeparatedValue, csvResults);
4647

4748
_clipboard.Flush();
49+
}
4850
}
4951
}
5052
}

Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,23 @@ protected override void OnExecute(object parameter)
8787
{
8888
while (index < text.Count)
8989
{
90-
var font = new Font(new FontFamily("Consolas"), 10, FontStyle.Regular);
91-
printPageArgs.Graphics.DrawString(text[index++], font, Brushes.Black, 0, offsetY, new StringFormat());
90+
using (var font = new Font(new FontFamily("Consolas"), 10, FontStyle.Regular))
91+
using (var stringFormat = new StringFormat())
92+
{
93+
printPageArgs.Graphics.DrawString(text[index++], font, Brushes.Black, 0, offsetY,
94+
stringFormat);
9295

93-
offsetY += font.Height;
96+
offsetY += font.Height;
9497

95-
if (offsetY >= pageHeight)
96-
{
97-
printPageArgs.HasMorePages = true;
98-
offsetY = 0;
99-
return;
100-
}
98+
if (offsetY >= pageHeight)
99+
{
100+
printPageArgs.HasMorePages = true;
101+
offsetY = 0;
102+
return;
103+
}
101104

102-
printPageArgs.HasMorePages = false;
105+
printPageArgs.HasMorePages = false;
106+
}
103107
}
104108
};
105109

Rubberduck.Core/UI/Command/ExportAllCommand.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,27 @@ private bool Evaluate(IVBProject project)
6161

6262
protected override void OnExecute(object parameter)
6363
{
64-
var projectNode = parameter as CodeExplorerProjectViewModel;
65-
66-
var vbproject = parameter as IVBProject;
64+
switch (parameter)
65+
{
66+
case CodeExplorerProjectViewModel projectNode when projectNode.Declaration.Project != null:
67+
Export(projectNode.Declaration.Project);
68+
break;
69+
case IVBProject vbproject:
70+
Export(vbproject);
71+
break;
72+
default:
73+
{
74+
using (var project = _vbe.ActiveVBProject)
75+
{
76+
Export(project);
77+
}
78+
break;
79+
}
80+
}
81+
}
6782

68-
var project = projectNode?.Declaration.Project ?? vbproject ?? _vbe.ActiveVBProject;
69-
83+
private void Export(IVBProject project)
84+
{
7085
var desc = string.Format(RubberduckUI.ExportAllCommand_SaveAsDialog_Title, project.Name);
7186

7287
// If .GetDirectoryName is passed an empty string for a RootFolder,

Rubberduck.Core/UI/Command/FindAllReferencesCommand.cs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -232,32 +232,47 @@ private Declaration FindFormDesignerTarget(QualifiedModuleName? qualifiedModuleN
232232
{
233233
projectId = activeProject.ProjectId;
234234
}
235-
var component = _vbe.SelectedVBComponent;
236235

237-
if (component?.HasDesigner ?? false)
236+
using (var component = _vbe.SelectedVBComponent)
238237
{
239-
DeclarationType selectedType;
240-
string selectedName;
241-
using (var selectedControls = component.SelectedControls)
238+
if (component?.HasDesigner ?? false)
242239
{
243-
var selectedCount = selectedControls.Count;
244-
if (selectedCount > 1)
240+
DeclarationType selectedType;
241+
string selectedName;
242+
using (var selectedControls = component.SelectedControls)
245243
{
246-
return null;
244+
var selectedCount = selectedControls.Count;
245+
if (selectedCount > 1)
246+
{
247+
return null;
248+
}
249+
250+
(selectedType, selectedName) = GetSelectedName(component, selectedControls, selectedCount);
247251
}
248252

249-
// Cannot use DeclarationType.UserForm, parser only assigns UserForms the ClassModule flag
250-
(selectedType, selectedName) = selectedCount == 0
251-
? (DeclarationType.ClassModule, component.Name)
252-
: (DeclarationType.Control, selectedControls[0].Name);
253+
return _state.DeclarationFinder
254+
.MatchName(selectedName)
255+
.SingleOrDefault(m => m.ProjectId == projectId
256+
&& m.DeclarationType.HasFlag(selectedType)
257+
&& m.ComponentName == component.Name);
253258
}
254-
return _state.DeclarationFinder
255-
.MatchName(selectedName)
256-
.SingleOrDefault(m => m.ProjectId == projectId
257-
&& m.DeclarationType.HasFlag(selectedType)
258-
&& m.ComponentName == component.Name);
259+
260+
return null;
261+
}
262+
}
263+
264+
private static (DeclarationType, string Name) GetSelectedName(IVBComponent component, IControls selectedControls, int selectedCount)
265+
{
266+
// Cannot use DeclarationType.UserForm, parser only assigns UserForms the ClassModule flag
267+
if (selectedCount == 0)
268+
{
269+
return (DeclarationType.ClassModule, component.Name);
270+
}
271+
272+
using (var firstSelectedControl = selectedControls[0])
273+
{
274+
return (DeclarationType.Control, firstSelectedControl.Name);
259275
}
260-
return null;
261276
}
262277

263278
private Declaration FindFormDesignerTarget(QualifiedModuleName qualifiedModuleName)

Rubberduck.Core/UI/Command/MenuItems/CommandBars/AppCommandBarBase.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,27 @@ public void EvaluateCanExecute(RubberduckParserState state)
169169
}
170170
}
171171

172-
public ICommandBars Parent { get; set; }
173-
public ICommandBar Item { get; private set; }
172+
private ICommandBars _parent;
173+
public ICommandBars Parent
174+
{
175+
get => _parent;
176+
set
177+
{
178+
_parent?.Dispose();
179+
_parent = value;
180+
}
181+
}
182+
183+
private ICommandBar _item;
184+
public ICommandBar Item
185+
{
186+
get => _item;
187+
private set
188+
{
189+
_item?.Dispose();
190+
_item = value;
191+
}
192+
}
174193

175194
public void RemoveCommandBar()
176195
{
@@ -181,9 +200,9 @@ public void RemoveCommandBar()
181200
Logger.Debug("Removing commandbar.");
182201
RemoveChildren();
183202
Item.Delete();
184-
Item.Dispose();
203+
204+
// Setting them to null will automatically dispose those
185205
Item = null;
186-
Parent?.Dispose();
187206
Parent = null;
188207
}
189208
}

0 commit comments

Comments
 (0)