Skip to content

Commit ac3a33a

Browse files
committed
Remove Linq from RubberduckParser
1 parent b2e89e1 commit ac3a33a

File tree

1 file changed

+143
-41
lines changed

1 file changed

+143
-41
lines changed

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 143 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
4-
using System.Linq;
54
using System.Threading;
65
using System.Threading.Tasks;
76
using Antlr4.Runtime;
@@ -16,6 +15,7 @@
1615
using Rubberduck.VBEditor.Extensions;
1716
using System.IO;
1817
using NLog;
18+
// ReSharper disable LoopCanBeConvertedToQuery
1919

2020
namespace Rubberduck.Parsing.VBA
2121
{
@@ -86,31 +86,46 @@ private void ReparseRequested(object sender, ParseRequestEventArgs e)
8686
/// </summary>
8787
public void Parse()
8888
{
89-
if (!_state.Projects.Any())
89+
if (_state.Projects.Count == 0)
9090
{
9191
foreach (var project in _vbe.VBProjects.UnprotectedProjects())
9292
{
9393
_state.AddProject(project);
9494
}
9595
}
9696

97-
var projects = _state.Projects.ToList();
97+
var components = new List<VBComponent>();
98+
foreach (var project in _state.Projects)
99+
{
100+
foreach (VBComponent component in project.VBComponents)
101+
{
102+
components.Add(component);
103+
}
104+
}
98105

99-
var components = projects.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
100-
SyncComReferences(projects);
106+
SyncComReferences(_state.Projects);
101107

102108
foreach (var component in components)
103109
{
104110
_state.SetModuleState(component, ParserState.Pending);
105111
}
106112

107113
// invalidation cleanup should go into ParseAsync?
108-
foreach (var invalidated in _componentAttributes.Keys.Except(components))
114+
foreach (var key in _componentAttributes.Keys)
115+
{
116+
if (!components.Contains(key))
117+
{
118+
_componentAttributes.Remove(key);
119+
}
120+
}
121+
122+
var parseTasks = new Task[components.Count];
123+
for (var i = 0; i < components.Count; i++)
109124
{
110-
_componentAttributes.Remove(invalidated);
125+
parseTasks[i] = ParseAsync(components[i], CancellationToken.None);
126+
parseTasks[i].Start();
111127
}
112128

113-
var parseTasks = components.Select(vbComponent => ParseAsync(vbComponent, CancellationToken.None)).ToArray();
114129
Task.WaitAll(parseTasks);
115130

116131
if (_state.Status != ParserState.Error)
@@ -125,24 +140,42 @@ public void Parse()
125140
/// </summary>
126141
private void ParseAll()
127142
{
128-
if (!_state.Projects.Any())
143+
if (_state.Projects.Count == 0)
129144
{
130145
foreach (var project in _vbe.VBProjects.UnprotectedProjects())
131146
{
132147
_state.AddProject(project);
133148
}
134149
}
135150

136-
var projects = _state.Projects.ToList();
137-
var components = projects.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
151+
var components = new List<VBComponent>();
152+
foreach (var project in _state.Projects)
153+
{
154+
foreach (VBComponent component in project.VBComponents)
155+
{
156+
components.Add(component);
157+
}
158+
}
138159

139-
var toParse = components.Where(c => _state.IsNewOrModified(c)).ToList();
140-
var unchanged = components.Where(c => !_state.IsNewOrModified(c)).ToList();
160+
var toParse = new List<VBComponent>();
161+
var unchanged = new List<VBComponent>();
141162

142-
SyncComReferences(projects);
143-
AddBuiltInDeclarations(projects);
163+
foreach (var component in components)
164+
{
165+
if (_state.IsNewOrModified(component))
166+
{
167+
toParse.Add(component);
168+
}
169+
else
170+
{
171+
unchanged.Add(component);
172+
}
173+
}
174+
175+
SyncComReferences(_state.Projects);
176+
AddBuiltInDeclarations(_state.Projects);
144177

145-
if (!toParse.Any())
178+
if (toParse.Count == 0)
146179
{
147180
State.SetStatusAndFireStateChanged(_state.Status);
148181
return;
@@ -161,17 +194,25 @@ private void ParseAll()
161194
_state.SetModuleState(component, ParserState.Ready);
162195
}
163196

164-
Debug.Assert(unchanged.All(component => _state.GetModuleState(component) == ParserState.Ready));
165-
Debug.Assert(toParse.All(component => _state.GetModuleState(component) == ParserState.Pending));
197+
//Debug.Assert(unchanged.All(component => _state.GetModuleState(component) == ParserState.Ready));
198+
//Debug.Assert(toParse.All(component => _state.GetModuleState(component) == ParserState.Pending));
166199
}
167200

168201
// invalidation cleanup should go into ParseAsync?
169-
foreach (var invalidated in _componentAttributes.Keys.Except(components))
202+
foreach (var key in _componentAttributes.Keys)
170203
{
171-
_componentAttributes.Remove(invalidated);
204+
if (!components.Contains(key))
205+
{
206+
_componentAttributes.Remove(key);
207+
}
208+
}
209+
210+
var parseTasks = new Task[components.Count];
211+
for (var i = 0; i < components.Count; i++)
212+
{
213+
parseTasks[i] = ParseAsync(components[i], CancellationToken.None);
172214
}
173215

174-
var parseTasks = toParse.Select(vbComponent => ParseAsync(vbComponent, CancellationToken.None)).ToArray();
175216
Task.WaitAll(parseTasks);
176217

177218
if (_state.Status != ParserState.Error)
@@ -184,12 +225,16 @@ private void ParseAll()
184225
private void AddBuiltInDeclarations(IReadOnlyList<VBProject> projects)
185226
{
186227
var finder = new DeclarationFinder(_state.AllDeclarations, new CommentNode[] { }, new IAnnotation[] { });
187-
if (finder.MatchName(Tokens.Err).Any(item => item.IsBuiltIn
188-
&& item.DeclarationType == DeclarationType.Variable
189-
&& item.Accessibility == Accessibility.Global))
228+
229+
foreach (var item in finder.MatchName(Tokens.Err))
190230
{
191-
return;
231+
if (item.IsBuiltIn && item.DeclarationType == DeclarationType.Variable &&
232+
item.Accessibility == Accessibility.Global)
233+
{
234+
return;
235+
}
192236
}
237+
193238
var vba = finder.FindProject("VBA");
194239
if (vba == null)
195240
{
@@ -213,21 +258,25 @@ private void AddBuiltInDeclarations(IReadOnlyList<VBProject> projects)
213258

214259
private string GetReferenceProjectId(Reference reference, IReadOnlyList<VBProject> projects)
215260
{
216-
var id = projects.FirstOrDefault(project =>
261+
VBProject project = null;
262+
foreach (var item in projects)
217263
{
218264
try
219265
{
220-
return project.FileName == reference.FullPath;
266+
if (item.FileName == reference.FullPath)
267+
{
268+
project = item;
269+
}
221270
}
222271
catch (IOException)
223272
{
224273
// Filename throws exception if unsaved.
225-
return false;
226274
}
227-
});
228-
if (id != null)
275+
}
276+
277+
if (project != null)
229278
{
230-
return QualifiedModuleName.GetProjectId(id);
279+
return QualifiedModuleName.GetProjectId(project);
231280
}
232281
return QualifiedModuleName.GetProjectId(reference);
233282
}
@@ -243,7 +292,16 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
243292
{
244293
var reference = vbProject.References.Item(priority);
245294
var referencedProjectId = GetReferenceProjectId(reference, projects);
246-
var map = _projectReferences.SingleOrDefault(r => r.ReferencedProjectId == referencedProjectId);
295+
296+
ReferencePriorityMap map = null;
297+
foreach (var item in _projectReferences)
298+
{
299+
if (item.ReferencedProjectId == referencedProjectId)
300+
{
301+
map = map != null ? null : item;
302+
}
303+
}
304+
247305
if (map == null)
248306
{
249307
map = new ReferencePriorityMap(referencedProjectId) { { projectId, priority } };
@@ -267,9 +325,24 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
267325
}
268326
}
269327

270-
var mappedIds = _projectReferences.Select(map => map.ReferencedProjectId);
271-
var unmapped = projects.SelectMany(project => project.References.Cast<Reference>())
272-
.Where(reference => !mappedIds.Contains(GetReferenceProjectId(reference, projects)));
328+
var mappedIds = new List<string>();
329+
foreach (var item in _projectReferences)
330+
{
331+
mappedIds.Add(item.ReferencedProjectId);
332+
}
333+
334+
var unmapped = new List<Reference>();
335+
foreach (var project in projects)
336+
{
337+
foreach (Reference item in project.References)
338+
{
339+
if (!mappedIds.Contains(GetReferenceProjectId(item, projects)))
340+
{
341+
unmapped.Add(item);
342+
}
343+
}
344+
}
345+
273346
foreach (var reference in unmapped)
274347
{
275348
UnloadComReference(reference, projects);
@@ -279,15 +352,24 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
279352
private void UnloadComReference(Reference reference, IReadOnlyList<VBProject> projects)
280353
{
281354
var referencedProjectId = GetReferenceProjectId(reference, projects);
282-
var map = _projectReferences.SingleOrDefault(r => r.ReferencedProjectId == referencedProjectId);
355+
356+
ReferencePriorityMap map = null;
357+
foreach (var item in _projectReferences)
358+
{
359+
if (item.ReferencedProjectId == referencedProjectId)
360+
{
361+
map = map != null ? null : item;
362+
}
363+
}
364+
283365
if (map == null || !map.IsLoaded)
284366
{
285367
// we're removing a reference we weren't tracking? ...this shouldn't happen.
286368
Debug.Assert(false);
287369
return;
288370
}
289371
map.Remove(referencedProjectId);
290-
if (!map.Any())
372+
if (map.Count == 0)
291373
{
292374
_projectReferences.Remove(map);
293375
_state.RemoveBuiltInDeclarations(reference);
@@ -390,9 +472,20 @@ private void Resolve(CancellationToken token)
390472

391473
private void ResolveInternal(CancellationToken token)
392474
{
393-
var components = _state.Projects
394-
.Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none)
395-
.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
475+
var components = new List<VBComponent>();
476+
foreach (var project in _state.Projects)
477+
{
478+
if (project.Protection == vbext_ProjectProtection.vbext_pp_locked)
479+
{
480+
continue;
481+
}
482+
483+
foreach (VBComponent component in project.VBComponents)
484+
{
485+
components.Add(component);
486+
}
487+
}
488+
396489
if (!_state.HasAllParseTrees(components))
397490
{
398491
return;
@@ -471,7 +564,16 @@ private Declaration CreateProjectDeclaration(QualifiedModuleName projectQualifie
471564
var qualifiedName = projectQualifiedName.QualifyMemberName(project.Name);
472565
var projectId = qualifiedName.QualifiedModuleName.ProjectId;
473566
var projectDeclaration = new ProjectDeclaration(qualifiedName, project.Name, isBuiltIn: false);
474-
var references = _projectReferences.Where(projectContainingReference => projectContainingReference.ContainsKey(projectId));
567+
568+
var references = new List<ReferencePriorityMap>();
569+
foreach (var item in _projectReferences)
570+
{
571+
if (item.ContainsKey(projectId))
572+
{
573+
references.Add(item);
574+
}
575+
}
576+
475577
foreach (var reference in references)
476578
{
477579
int priority = reference[projectId];

0 commit comments

Comments
 (0)