Skip to content

Commit 10c9cc1

Browse files
committed
Hopefully, guard the users of ProjectDeclaration.Project correctly against the null returned after disposal.
1 parent 68dfa8e commit 10c9cc1

File tree

11 files changed

+65
-23
lines changed

11 files changed

+65
-23
lines changed

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerProjectViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public CodeExplorerProjectViewModel(FolderHelper folderHelper, Declaration decla
3636
FillFolders(declarations.ToList());
3737
Items = _folderTree.Items.ToList();
3838

39-
_icon = Declaration.Project.Protection == ProjectProtection.Locked
39+
_icon = Declaration.Project?.Protection == ProjectProtection.Locked
4040
? GetImageSource(resx.lock__exclamation)
4141
: GetImageSource(resx.ObjectLibrary);
4242
}

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ private void ParserState_ModuleStateChanged(object sender, Parsing.ParseProgress
373373
var componentProject = _state.ProjectsProvider.Project(e.Module.ProjectId);
374374
{
375375
var projectNode = Projects.OfType<CodeExplorerProjectViewModel>()
376-
.FirstOrDefault(p => p.Declaration.Project.Equals(componentProject));
376+
.FirstOrDefault(p => p.Declaration.Project?.Equals(componentProject) ?? false);
377377

378378
if (projectNode == null)
379379
{

RetailCoder.VBE/Refactorings/ExtractInterface/ExtractInterfacePresenter.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Linq;
22
using System.Windows.Forms;
3+
using Rubberduck.Parsing.Symbols;
34
using Rubberduck.UI.Refactorings;
45

56
namespace Rubberduck.Refactorings.ExtractInterface
@@ -27,7 +28,11 @@ public ExtractInterfaceModel Show()
2728
return null;
2829
}
2930

30-
_view.ViewModel.ComponentNames = _model.TargetDeclaration.Project.VBComponents.Select(c => c.Name).ToList();
31+
_view.ViewModel.ComponentNames = _model.State.DeclarationFinder
32+
.UserDeclarations(DeclarationType.Module)
33+
.Where(moduleDeclaration => moduleDeclaration.ProjectId == _model.TargetDeclaration.ProjectId)
34+
.Select(module => module.ComponentName)
35+
.ToList();
3136
_view.ViewModel.InterfaceName = _model.InterfaceName;
3237
_view.ViewModel.Members = _model.Members.ToList();
3338

RetailCoder.VBE/Refactorings/ExtractInterface/ExtractInterfaceRefactoring.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ public void Refactor(Declaration target)
8787

8888
private void AddInterface()
8989
{
90+
var targetProject = _model.TargetDeclaration.Project;
91+
if (targetProject == null)
92+
{
93+
return; //The target project is not available.
94+
}
95+
9096
var rewriter = _model.State.GetRewriter(_model.TargetDeclaration);
9197

9298
var firstNonFieldMember = _model.State.DeclarationFinder.Members(_model.TargetDeclaration)
@@ -96,7 +102,7 @@ private void AddInterface()
96102

97103
AddInterfaceMembersToClass(rewriter);
98104

99-
using (var components = _model.TargetDeclaration.Project.VBComponents)
105+
using (var components = targetProject.VBComponents)
100106
{
101107
using (var interfaceComponent = components.Add(ComponentType.ClassModule))
102108
{

RetailCoder.VBE/UI/CodeExplorer/Commands/AddComponentCommand.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,14 @@ public bool CanAddComponent(CodeExplorerItemViewModel parameter)
3030

3131
public void AddComponent(CodeExplorerItemViewModel node, ComponentType type)
3232
{
33+
var nodeProject = GetDeclaration(node)?.Project;
34+
if (node != null && nodeProject == null)
35+
{
36+
return; //The project is not available.
37+
}
38+
3339
using (var components = node != null
34-
? GetDeclaration(node).Project.VBComponents
40+
? nodeProject.VBComponents
3541
: ComponentsCollectionFromActiveProject())
3642
{
3743
var folderAnnotation = $"'@Folder(\"{GetFolder(node)}\")";

RetailCoder.VBE/UI/CodeExplorer/Commands/AddTestModuleCommand.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ protected override bool EvaluateCanExecute(object parameter)
2323
{
2424
try
2525
{
26-
return GetDeclaration(parameter) != null || _vbe.ProjectsCount == 1;
26+
return GetDeclaration(parameter)?.Project != null || _vbe.ProjectsCount == 1;
2727
}
2828
catch (COMException)
2929
{
@@ -33,8 +33,14 @@ protected override bool EvaluateCanExecute(object parameter)
3333

3434
protected override void OnExecute(object parameter)
3535
{
36+
var parameterProject = GetDeclaration(parameter)?.Project;
37+
if (parameter != null && parameterProject == null)
38+
{
39+
return; //The project selected module is not available.
40+
}
41+
3642
_newUnitTestModuleCommand.Execute(parameter != null
37-
? GetDeclaration(parameter).Project
43+
? parameterProject
3844
: _vbe.ActiveVBProject);
3945
}
4046

RetailCoder.VBE/UI/CodeExplorer/Commands/IndentCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override bool EvaluateCanExecute(object parameter)
5151
return _state.AllUserDeclarations
5252
.Any(c => c.DeclarationType.HasFlag(DeclarationType.Module) &&
5353
c.Annotations.All(a => a.AnnotationType != AnnotationType.NoIndent) &&
54-
c.Project == declaration.Project);
54+
c.ProjectId == declaration.ProjectId);
5555
}
5656

5757
if (parameter is CodeExplorerCustomFolderViewModel)

RetailCoder.VBE/UI/CodeExplorer/Commands/OpenProjectPropertiesCommand.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using Rubberduck.Navigation.CodeExplorer;
44
using Rubberduck.UI.Command;
55
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
6-
using Rubberduck.VBEditor.SafeComWrappers.Office.Core.Abstract;
76

87
namespace Rubberduck.UI.CodeExplorer.Commands
98
{
@@ -50,9 +49,15 @@ protected override void OnExecute(object parameter)
5049
node = node.Parent; // the project node is an ICodeExplorerDeclarationViewModel--no worries here
5150
}
5251

52+
var nodeProject = node.GetSelectedDeclaration().Project;
53+
if (nodeProject == null)
54+
{
55+
return; //The project declaration has been disposed, i.e. the project has been removed already.
56+
}
57+
5358
try
5459
{
55-
_vbe.ActiveVBProject = node.GetSelectedDeclaration().Project;
60+
_vbe.ActiveVBProject = nodeProject;
5661
}
5762
catch (COMException)
5863
{

RetailCoder.VBE/UI/Command/AddTestModuleCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ protected override void OnExecute(object parameter)
147147
var project = parameter as IVBProject ??
148148
(parameterIsModuleDeclaration ? ((Declaration) parameter).Project : GetProject());
149149

150-
if (project.IsWrappingNullReference)
150+
if (project == null || project.IsWrappingNullReference)
151151
{
152152
return;
153153
}

RetailCoder.VBE/UI/Command/RunAllTestsCommand.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Rubberduck.UI.UnitTesting;
66
using Rubberduck.UnitTesting;
77
using System.Linq;
8+
using Rubberduck.Parsing.Symbols;
89
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
910

1011
namespace Rubberduck.UI.Command
@@ -54,13 +55,19 @@ protected override void OnExecute(object parameter)
5455

5556
private void EnsureRubberduckIsReferencedForEarlyBoundTests()
5657
{
57-
foreach (var member in _state.AllUserDeclarations)
58+
var projectIdsOfMembersUsingAddInLibrary = _state.DeclarationFinder.AllUserDeclarations
59+
.Where(member => member.AsTypeName == "Rubberduck.PermissiveAssertClass"
60+
|| member.AsTypeName == "Rubberduck.AssertClass")
61+
.Select(member => member.ProjectId)
62+
.ToHashSet();
63+
var projectsUsingAddInLibrary = _state.DeclarationFinder
64+
.UserDeclarations(DeclarationType.Project)
65+
.Where(declaration => projectIdsOfMembersUsingAddInLibrary.Contains(declaration.ProjectId))
66+
.Select(declaration => declaration.Project);
67+
68+
foreach (var project in projectsUsingAddInLibrary)
5869
{
59-
if (member.AsTypeName == "Rubberduck.PermissiveAssertClass" ||
60-
member.AsTypeName == "Rubberduck.AssertClass")
61-
{
62-
member.Project.EnsureReferenceToAddInLibrary();
63-
}
70+
project?.EnsureReferenceToAddInLibrary();
6471
}
6572
}
6673

0 commit comments

Comments
 (0)