Skip to content

Commit 747189b

Browse files
authored
Merge pull request #4727 from comintern/next
Code Explorer hotfix
2 parents 81a2626 + 320ee73 commit 747189b

27 files changed

+3388
-473
lines changed

Rubberduck.Core/AddRemoveReferences/ReferenceModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public bool Matches(ReferenceInfo info)
183183
FullPath.Equals(info.FullPath, StringComparison.OrdinalIgnoreCase) ||
184184
FullPath32.Equals(info.FullPath, StringComparison.OrdinalIgnoreCase) ||
185185
FullPath64.Equals(info.FullPath, StringComparison.OrdinalIgnoreCase) ||
186-
Guid.Equals(info.Guid);
186+
!Guid.Equals(Guid.Empty) && Guid.Equals(info.Guid);
187187
}
188188

189189
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")

Rubberduck.Core/CodeAnalysis/CodeMetrics/CodeMetricsViewModel.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,39 +54,37 @@ private void OnStateChanged(object sender, ParserStateEventArgs e)
5454
Unparsed = false;
5555
IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;
5656

57-
if (e.State != ParserState.ResolvedDeclarations)
57+
if (e.State == ParserState.ResolvedDeclarations)
5858
{
59-
return;
59+
Synchronize(_state.DeclarationFinder.AllUserDeclarations);
6060
}
61-
62-
Synchronize(_state.DeclarationFinder.AllUserDeclarations.ToList());
6361
}
6462

65-
private void Synchronize(List<Declaration> declarations)
63+
private void Synchronize(IEnumerable<Declaration> declarations)
6664
{
6765
var metricResults = _analyst.GetMetrics(_state);
6866
_resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());
6967

7068
_uiDispatcher.Invoke(() =>
7169
{
70+
var updates = declarations.ToList();
7271
var existing = Projects.OfType<CodeExplorerProjectViewModel>().ToList();
7372

7473
foreach (var project in existing)
7574
{
76-
project.Synchronize(declarations);
75+
project.Synchronize(ref updates);
7776
if (project.Declaration is null)
7877
{
7978
Projects.Remove(project);
8079
}
8180
}
8281

83-
var adding = declarations.OfType<ProjectDeclaration>().ToList();
82+
var adding = updates.OfType<ProjectDeclaration>().ToList();
8483

8584
foreach (var project in adding)
8685
{
87-
var model = new CodeExplorerProjectViewModel(project, declarations.Where(proj => proj.ProjectId.Equals(project.ProjectId)).ToList(), _state, _vbe, false);
86+
var model = new CodeExplorerProjectViewModel(project, ref updates, _state, _vbe, false);
8887
Projects.Add(model);
89-
model.IsExpanded = true;
9088
}
9189
});
9290
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ public sealed class CodeExplorerComponentViewModel : CodeExplorerItemViewModel
3030

3131
private readonly IVBE _vbe;
3232

33-
public CodeExplorerComponentViewModel(ICodeExplorerNode parent, Declaration declaration, IEnumerable<Declaration> declarations, IVBE vbe)
33+
public CodeExplorerComponentViewModel(ICodeExplorerNode parent, Declaration declaration, ref List<Declaration> declarations, IVBE vbe)
3434
: base(parent, declaration)
3535
{
3636
_vbe = vbe;
3737
SetName();
38-
AddNewChildren(declarations.ToList());
38+
AddNewChildren(ref declarations);
3939
}
4040

4141
private string _name;
@@ -54,9 +54,9 @@ public CodeExplorerComponentViewModel(ICodeExplorerNode parent, Declaration decl
5454
public bool IsTestModule => Declaration.DeclarationType == DeclarationType.ProceduralModule
5555
&& Declaration.Annotations.Any(annotation => annotation.AnnotationType == AnnotationType.TestModule);
5656

57-
public override void Synchronize(List<Declaration> updated)
57+
public override void Synchronize(ref List<Declaration> updated)
5858
{
59-
base.Synchronize(updated);
59+
base.Synchronize(ref updated);
6060
if (Declaration is null)
6161
{
6262
return;
@@ -66,18 +66,23 @@ public override void Synchronize(List<Declaration> updated)
6666
SetName();
6767
}
6868

69-
protected override void AddNewChildren(List<Declaration> updated)
69+
protected override void AddNewChildren(ref List<Declaration> updated)
7070
{
7171
if (updated is null)
7272
{
7373
return;
7474
}
7575

76-
AddChildren(updated.GroupBy(item => item.Scope).SelectMany(grouping =>
77-
grouping.Where(item =>
78-
item.ParentDeclaration != null && item.ParentScope == Declaration.Scope &&
79-
MemberTypes.Contains(item.DeclarationType))
80-
.Select(item => new CodeExplorerMemberViewModel(this, item, grouping))));
76+
var children = updated.Where(declaration =>
77+
!ReferenceEquals(Declaration, declaration) &&
78+
declaration.QualifiedModuleName.Equals(Declaration?.QualifiedModuleName)).ToList();
79+
80+
updated = updated.Except(children.Concat(new [] { Declaration })).ToList();
81+
82+
foreach (var member in children.Where(declaration => MemberTypes.Contains(declaration.DeclarationType)).ToList())
83+
{
84+
AddChild(new CodeExplorerMemberViewModel(this, member, ref children));
85+
}
8186
}
8287

8388
private void SetName()
@@ -96,8 +101,7 @@ private void SetName()
96101
switch (qualifiedModuleName.ComponentType)
97102
{
98103
case ComponentType.Document:
99-
100-
using (var app = _vbe.HostApplication())
104+
using (var app = _vbe?.HostApplication())
101105
{
102106
var parenthesized = app?.GetDocument(qualifiedModuleName)?.DocumentName ?? string.Empty;
103107
_name = string.IsNullOrEmpty(parenthesized) ? _name : $"{_name} ({parenthesized})";

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Rubberduck.Navigation.CodeExplorer
1010
{
11-
[DebuggerDisplay("{Name}")]
11+
[DebuggerDisplay("{" + nameof(Name) + "}")]
1212
public sealed class CodeExplorerCustomFolderViewModel : CodeExplorerItemViewModel
1313
{
1414
private static readonly DeclarationType[] ComponentTypes =
@@ -26,14 +26,14 @@ public CodeExplorerCustomFolderViewModel(
2626
string name,
2727
string fullPath,
2828
IVBE vbe,
29-
IEnumerable<Declaration> declarations) : base(parent, parent?.Declaration)
29+
ref List<Declaration> declarations) : base(parent, parent?.Declaration)
3030
{
3131
_vbe = vbe;
3232
FolderDepth = parent is CodeExplorerCustomFolderViewModel folder ? folder.FolderDepth + 1 : 1;
3333
FullPath = fullPath?.Trim('"') ?? string.Empty;
3434
Name = name.Replace("\"", string.Empty);
3535

36-
AddNewChildren(declarations.ToList());
36+
AddNewChildren(ref declarations);
3737
}
3838

3939
public override string Name { get; }
@@ -63,84 +63,78 @@ public override bool IsErrorState
6363

6464
public override bool Filtered => false;
6565

66-
protected override void AddNewChildren(List<Declaration> declarations)
66+
protected override void AddNewChildren(ref List<Declaration> declarations)
6767
{
68-
var children = declarations.Where(declaration => declaration.IsInSubFolder(FullPath)).ToList();
68+
var children = declarations.Where(declaration => declaration.IsInFolderOrSubFolder(FullPath)).ToList();
69+
declarations = declarations.Except(children).ToList();
6970

70-
foreach (var folder in children.GroupBy(declaration => declaration.CustomFolder.SubFolderRoot(FullPath)))
71+
var subFolders = children.Where(declaration => declaration.IsInSubFolder(FullPath)).ToList();
72+
73+
foreach (var folder in subFolders.GroupBy(declaration => declaration.CustomFolder.SubFolderRoot(FullPath)))
7174
{
72-
AddChild(new CodeExplorerCustomFolderViewModel(this, folder.Key, $"{FullPath}.{folder.Key}", _vbe, folder));
73-
foreach (var declaration in folder)
74-
{
75-
declarations.Remove(declaration);
76-
}
75+
var contents = folder.ToList();
76+
AddChild(new CodeExplorerCustomFolderViewModel(this, folder.Key, $"{FullPath}.{folder.Key}", _vbe, ref contents));
7777
}
7878

79-
foreach (var declaration in declarations.Where(child => child.IsInFolder(FullPath)).GroupBy(item => item.ComponentName))
79+
children = children.Except(subFolders).ToList();
80+
81+
foreach (var declaration in children.Where(child => child.IsInFolder(FullPath)).GroupBy(item => item.ComponentName))
8082
{
8183
var moduleName = declaration.Key;
82-
var parent = declarations.SingleOrDefault(item =>
84+
var parent = children.SingleOrDefault(item =>
8385
ComponentTypes.Contains(item.DeclarationType) && item.ComponentName == moduleName);
8486

8587
if (parent is null)
8688
{
8789
continue;
8890
}
8991

90-
var members = declarations.Where(item =>
91-
!ComponentTypes.Contains(item.DeclarationType) && item.ComponentName == moduleName);
92+
var members = children.Where(item =>
93+
!ComponentTypes.Contains(item.DeclarationType) && item.ComponentName == moduleName).ToList();
9294

93-
AddChild(new CodeExplorerComponentViewModel(this, parent, members, _vbe));
94-
declarations.Remove(parent);
95+
AddChild(new CodeExplorerComponentViewModel(this, parent, ref members, _vbe));
9596
}
9697
}
9798

98-
public override void Synchronize(List<Declaration> updated)
99+
public override void Synchronize(ref List<Declaration> updated)
99100
{
100-
SynchronizeChildren(updated);
101+
SynchronizeChildren(ref updated);
101102
}
102103

103-
protected override void SynchronizeChildren(List<Declaration> updated)
104+
protected override void SynchronizeChildren(ref List<Declaration> updated)
104105
{
105-
var declarations = updated.Where(declaration => declaration.IsInFolderOrSubFolder(FullPath)).ToList();
106-
107-
if (!declarations.Any())
106+
var children = updated.Where(declaration => declaration.IsInFolderOrSubFolder(FullPath)).ToList();
107+
updated = updated.Except(children).ToList();
108+
109+
if (!children.Any())
108110
{
109111
Declaration = null;
110112
return;
111113
}
112114

113-
var synchronizing = declarations.ToList();
115+
var subFolders = children.Where(declaration => declaration.IsInSubFolder(FullPath)).ToList();
116+
children = children.Except(subFolders).ToList();
114117

115118
foreach (var subfolder in Children.OfType<CodeExplorerCustomFolderViewModel>().ToList())
116119
{
117-
subfolder.SynchronizeChildren(declarations);
120+
subfolder.SynchronizeChildren(ref subFolders);
118121
if (subfolder.Declaration is null)
119122
{
120123
RemoveChild(subfolder);
121-
continue;
122-
}
123-
124-
var synchronized = synchronizing.Where(child => !declarations.Contains(child)).ToList();
125-
foreach (var declaration in synchronized)
126-
{
127-
updated.Remove(declaration);
128124
}
129125
}
130126

131127
foreach (var child in Children.OfType<CodeExplorerComponentViewModel>().ToList())
132128
{
133-
child.Synchronize(updated);
129+
child.Synchronize(ref children);
134130
if (child.Declaration is null)
135131
{
136132
RemoveChild(child);
137-
continue;
138133
}
139-
140-
updated.Remove(child.Declaration);
141134
}
142135

143-
AddNewChildren(updated);
136+
children = children.Concat(subFolders).ToList();
137+
AddNewChildren(ref children);
144138
}
145139
}
146140
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModel.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ public override bool IsErrorState
3434
}
3535
}
3636

37-
public virtual void Synchronize(List<Declaration> updated)
37+
public virtual void Synchronize(ref List<Declaration> updated)
3838
{
3939
if (Declaration is null)
4040
{
4141
return;
4242
}
4343

44-
var matching = updated.FirstOrDefault(decl => Declaration.DeclarationType == decl?.DeclarationType && Declaration.QualifiedName.Equals(decl?.QualifiedName));
44+
var matching = updated.FirstOrDefault(decl =>
45+
Declaration.DeclarationType == decl?.DeclarationType &&
46+
Declaration.QualifiedName.Equals(decl.QualifiedName));
4547

4648
if (matching is null)
4749
{
@@ -51,14 +53,14 @@ public virtual void Synchronize(List<Declaration> updated)
5153

5254
Declaration = matching;
5355
updated.Remove(matching);
54-
SynchronizeChildren(updated);
56+
SynchronizeChildren(ref updated);
5557
}
5658

57-
protected virtual void SynchronizeChildren(List<Declaration> updated)
59+
protected virtual void SynchronizeChildren(ref List<Declaration> updated)
5860
{
5961
foreach (var child in Children.OfType<CodeExplorerItemViewModel>().ToList())
6062
{
61-
child.Synchronize(updated);
63+
child.Synchronize(ref updated);
6264
if (child.Declaration is null)
6365
{
6466
RemoveChild(child);
@@ -68,9 +70,9 @@ protected virtual void SynchronizeChildren(List<Declaration> updated)
6870
updated.Remove(child.Declaration);
6971
}
7072

71-
AddNewChildren(updated);
73+
AddNewChildren(ref updated);
7274
}
7375

74-
protected abstract void AddNewChildren(List<Declaration> updated);
76+
protected abstract void AddNewChildren(ref List<Declaration> updated);
7577
}
7678
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModelBase.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
4-
using System.Diagnostics.CodeAnalysis;
54
using System.Globalization;
65
using System.Linq;
76
using System.Windows;
@@ -75,13 +74,12 @@ public virtual string PanelTitle
7574

7675
public virtual string Description => Declaration?.DescriptionString ?? string.Empty;
7776

78-
[SuppressMessage("ReSharper", "ExplicitCallerInfoArgument")]
7977
protected void OnNameChanged()
8078
{
81-
OnPropertyChanged("Name");
82-
OnPropertyChanged("NameWithSignature");
83-
OnPropertyChanged("PanelTitle");
84-
OnPropertyChanged("Description");
79+
OnPropertyChanged(nameof(Name));
80+
OnPropertyChanged(nameof(NameWithSignature));
81+
OnPropertyChanged(nameof(PanelTitle));
82+
OnPropertyChanged(nameof(Description));
8583
}
8684

8785
public virtual QualifiedSelection? QualifiedSelection => Declaration?.QualifiedSelection;
@@ -232,8 +230,7 @@ public string Filter
232230
}
233231

234232
OnPropertyChanged();
235-
// ReSharper disable once ExplicitCallerInfoArgument
236-
OnPropertyChanged("Filtered");
233+
OnPropertyChanged(nameof(Filtered));
237234
}
238235
}
239236

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerMemberViewModel.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
namespace Rubberduck.Navigation.CodeExplorer
99
{
10-
public class CodeExplorerMemberViewModel : CodeExplorerItemViewModel
10+
public sealed class CodeExplorerMemberViewModel : CodeExplorerItemViewModel
1111
{
12-
public CodeExplorerMemberViewModel(ICodeExplorerNode parent, Declaration declaration, IEnumerable<Declaration> declarations) : base(parent, declaration)
12+
public CodeExplorerMemberViewModel(ICodeExplorerNode parent, Declaration declaration, ref List<Declaration> declarations) : base(parent, declaration)
1313
{
14-
AddNewChildren(declarations.ToList());
14+
AddNewChildren(ref declarations);
1515
Name = DetermineMemberName(declaration);
1616
}
1717

@@ -59,9 +59,9 @@ public override string NameWithSignature
5959
DeclarationType.UserDefinedTypeMember
6060
};
6161

62-
public override void Synchronize(List<Declaration> updated)
62+
public override void Synchronize(ref List<Declaration> updated)
6363
{
64-
base.Synchronize(updated);
64+
base.Synchronize(ref updated);
6565
if (Declaration is null)
6666
{
6767
return;
@@ -72,15 +72,19 @@ public override void Synchronize(List<Declaration> updated)
7272
OnNameChanged();
7373
}
7474

75-
protected sealed override void AddNewChildren(List<Declaration> updated)
75+
protected override void AddNewChildren(ref List<Declaration> updated)
7676
{
77-
if (updated != null)
77+
if (updated == null)
7878
{
79-
AddChildren(updated
80-
.Where(item =>
81-
SubMemberTypes.Contains(item.DeclarationType) && item.ParentDeclaration.Equals(Declaration))
82-
.Select(item => new CodeExplorerSubMemberViewModel(this, item)));
79+
return;
8380
}
81+
82+
var updates = updated.Where(item =>
83+
SubMemberTypes.Contains(item.DeclarationType) && item.ParentDeclaration.Equals(Declaration)).ToList();
84+
85+
updated = updated.Except(updates.Concat(new[] { Declaration })).ToList();
86+
87+
AddChildren(updates.Select(item => new CodeExplorerSubMemberViewModel(this, item)));
8488
}
8589

8690
public override Comparer<ICodeExplorerNode> SortComparer

0 commit comments

Comments
 (0)