Skip to content

Commit 2fb73ef

Browse files
committed
Restructure to make list handling more efficient, add tests.
1 parent 72fcdb2 commit 2fb73ef

17 files changed

+988
-186
lines changed

Rubberduck.Core/CodeAnalysis/CodeMetrics/CodeMetricsViewModel.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,35 +56,35 @@ private void OnStateChanged(object sender, ParserStateEventArgs e)
5656

5757
if (e.State == ParserState.ResolvedDeclarations)
5858
{
59-
Synchronize(_state.DeclarationFinder.AllUserDeclarations.ToList());
59+
Synchronize(_state.DeclarationFinder.AllUserDeclarations);
6060
}
6161
}
6262

63-
private void Synchronize(List<Declaration> declarations)
63+
private void Synchronize(IEnumerable<Declaration> declarations)
6464
{
6565
var metricResults = _analyst.GetMetrics(_state);
6666
_resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());
6767

6868
_uiDispatcher.Invoke(() =>
6969
{
70+
var updates = declarations.ToList();
7071
var existing = Projects.OfType<CodeExplorerProjectViewModel>().ToList();
7172

7273
foreach (var project in existing)
7374
{
74-
project.Synchronize(declarations);
75+
project.Synchronize(ref updates);
7576
if (project.Declaration is null)
7677
{
7778
Projects.Remove(project);
7879
}
7980
}
8081

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

8384
foreach (var project in adding)
8485
{
85-
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);
8687
Projects.Add(model);
87-
model.IsExpanded = true;
8888
}
8989
});
9090
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs

Lines changed: 12 additions & 13 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,23 +66,22 @@ 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-
var children = updated
77-
.Where(declaration => declaration.ParentDeclaration != null &&
78-
MemberTypes.Contains(declaration.DeclarationType) &&
79-
declaration.ParentScope.Equals(Declaration.Scope, StringComparison.OrdinalIgnoreCase))
80-
.ToList();
76+
var children = updated.Where(declaration =>
77+
!ReferenceEquals(Declaration, declaration) &&
78+
declaration.QualifiedModuleName.Equals(Declaration?.QualifiedModuleName)).ToList();
8179

82-
foreach (var member in children)
80+
updated = updated.Except(children.Concat(new [] { Declaration })).ToList();
81+
82+
foreach (var member in children.Where(declaration => MemberTypes.Contains(declaration.DeclarationType)).ToList())
8383
{
84-
AddChild(new CodeExplorerMemberViewModel(this, member, updated));
85-
updated.Remove(member);
84+
AddChild(new CodeExplorerMemberViewModel(this, member, ref children));
8685
}
8786
}
8887

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs

Lines changed: 29 additions & 36 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,77 @@ 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+
var children = updated.Where(declaration => declaration.IsInFolderOrSubFolder(FullPath)).ToList();
107+
updated = updated.Except(children).ToList();
106108

107-
if (!declarations.Any())
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+
AddNewChildren(ref children);
144137
}
145138
}
146139
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModel.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ 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
{
@@ -53,14 +53,14 @@ public virtual void Synchronize(List<Declaration> updated)
5353

5454
Declaration = matching;
5555
updated.Remove(matching);
56-
SynchronizeChildren(updated);
56+
SynchronizeChildren(ref updated);
5757
}
5858

59-
protected virtual void SynchronizeChildren(List<Declaration> updated)
59+
protected virtual void SynchronizeChildren(ref List<Declaration> updated)
6060
{
6161
foreach (var child in Children.OfType<CodeExplorerItemViewModel>().ToList())
6262
{
63-
child.Synchronize(updated);
63+
child.Synchronize(ref updated);
6464
if (child.Declaration is null)
6565
{
6666
RemoveChild(child);
@@ -70,9 +70,9 @@ protected virtual void SynchronizeChildren(List<Declaration> updated)
7070
updated.Remove(child.Declaration);
7171
}
7272

73-
AddNewChildren(updated);
73+
AddNewChildren(ref updated);
7474
}
7575

76-
protected abstract void AddNewChildren(List<Declaration> updated);
76+
protected abstract void AddNewChildren(ref List<Declaration> updated);
7777
}
7878
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerMemberViewModel.cs

Lines changed: 14 additions & 16 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, List<Declaration> declarations) : base(parent, declaration)
12+
public CodeExplorerMemberViewModel(ICodeExplorerNode parent, Declaration declaration, ref List<Declaration> declarations) : base(parent, declaration)
1313
{
14-
AddNewChildren(declarations);
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,21 +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-
var updates = updated.Where(item =>
80-
SubMemberTypes.Contains(item.DeclarationType) && item.ParentDeclaration.Equals(Declaration))
81-
.ToList();
79+
return;
80+
}
8281

83-
AddChildren(updates.Select(item => new CodeExplorerSubMemberViewModel(this, item)));
82+
var updates = updated.Where(item =>
83+
SubMemberTypes.Contains(item.DeclarationType) && item.ParentDeclaration.Equals(Declaration)).ToList();
8484

85-
foreach (var declaration in updates)
86-
{
87-
updated.Remove(declaration);
88-
}
89-
}
85+
updated = updated.Except(updates.Concat(new[] { Declaration })).ToList();
86+
87+
AddChildren(updates.Select(item => new CodeExplorerSubMemberViewModel(this, item)));
9088
}
9189

9290
public override Comparer<ICodeExplorerNode> SortComparer

0 commit comments

Comments
 (0)