@@ -16,7 +16,7 @@ namespace Rubberduck.Parsing.Symbols
16
16
internal static class DictionaryExtensions
17
17
{
18
18
public static IEnumerable < TValue > AllValues < TKey , TValue > (
19
- this IDictionary < TKey , TValue [ ] > source )
19
+ this ConcurrentDictionary < TKey , ConcurrentBag < TValue > > source )
20
20
{
21
21
return source . SelectMany ( item => item . Value ) . ToList ( ) ;
22
22
}
@@ -26,6 +26,11 @@ public static IEnumerable<TValue> AllValues<TKey, TValue>(
26
26
{
27
27
return source . SelectMany ( item => item . Value ) . ToList ( ) ;
28
28
}
29
+
30
+ public static ConcurrentDictionary < TKey , ConcurrentBag < TValue > > ToConcurrentDictionary < TKey , TValue > ( this IEnumerable < IGrouping < TKey , TValue > > source )
31
+ {
32
+ return new ConcurrentDictionary < TKey , ConcurrentBag < TValue > > ( source . Select ( x => new KeyValuePair < TKey , ConcurrentBag < TValue > > ( x . Key , new ConcurrentBag < TValue > ( x ) ) ) ) ;
33
+ }
29
34
}
30
35
31
36
public class DeclarationFinder
@@ -35,14 +40,14 @@ public class DeclarationFinder
35
40
36
41
private readonly IHostApplication _hostApp ;
37
42
private readonly AnnotationService _annotationService ;
38
- private readonly ConcurrentDictionary < string , Declaration [ ] > _declarationsByName ;
39
- private readonly ConcurrentDictionary < QualifiedModuleName , Declaration [ ] > _declarations ;
40
- private readonly ConcurrentDictionary < QualifiedMemberName , IList < Declaration > > _undeclared ;
43
+ private readonly ConcurrentDictionary < string , ConcurrentBag < Declaration > > _declarationsByName ;
44
+ private readonly ConcurrentDictionary < QualifiedModuleName , ConcurrentBag < Declaration > > _declarations ;
45
+ private readonly ConcurrentDictionary < QualifiedMemberName , ConcurrentBag < Declaration > > _undeclared ;
41
46
private readonly ConcurrentBag < UnboundMemberDeclaration > _unresolved ;
42
- private readonly ConcurrentDictionary < QualifiedModuleName , IAnnotation [ ] > _annotations ;
43
- private readonly ConcurrentDictionary < Declaration , Declaration [ ] > _parametersByParent ;
44
- private readonly ConcurrentDictionary < DeclarationType , Declaration [ ] > _userDeclarationsByType ;
45
-
47
+ private readonly ConcurrentDictionary < QualifiedModuleName , ConcurrentBag < IAnnotation > > _annotations ;
48
+ private readonly ConcurrentDictionary < Declaration , ConcurrentBag < Declaration > > _parametersByParent ;
49
+ private readonly ConcurrentDictionary < DeclarationType , ConcurrentBag < Declaration > > _userDeclarationsByType ;
50
+
46
51
private readonly Lazy < ConcurrentDictionary < Declaration , Declaration [ ] > > _handlersByWithEventsField ;
47
52
private readonly Lazy < ConcurrentDictionary < VBAParser . ImplementsStmtContext , Declaration [ ] > > _membersByImplementsContext ;
48
53
private readonly Lazy < ConcurrentDictionary < Declaration , Declaration [ ] > > _interfaceMembers ;
@@ -52,26 +57,16 @@ public class DeclarationFinder
52
57
public DeclarationFinder ( IReadOnlyList < Declaration > declarations , IEnumerable < IAnnotation > annotations , IHostApplication hostApp = null )
53
58
{
54
59
_hostApp = hostApp ;
55
- _annotations = new ConcurrentDictionary < QualifiedModuleName , IAnnotation [ ] > ( annotations . GroupBy ( node => node . QualifiedSelection . QualifiedName )
56
- . ToDictionary ( grouping => grouping . Key , grouping => grouping . ToArray ( ) ) ) ;
57
- _declarations = new ConcurrentDictionary < QualifiedModuleName , Declaration [ ] > ( declarations . GroupBy ( item => item . QualifiedName . QualifiedModuleName )
58
- . ToDictionary ( grouping => grouping . Key , grouping => grouping . ToArray ( ) ) ) ;
59
-
60
- _declarationsByName = new ConcurrentDictionary < string , Declaration [ ] > (
61
- declarations . GroupBy ( declaration => new { IdentifierName = declaration . IdentifierName . ToLowerInvariant ( ) } )
62
- . ToDictionary ( grouping => grouping . Key . IdentifierName , grouping => grouping . ToArray ( ) , NameComparer ) ) ;
63
- _parametersByParent = new ConcurrentDictionary < Declaration , Declaration [ ] > (
64
- declarations . Where ( declaration => declaration . DeclarationType == DeclarationType . Parameter )
65
- . GroupBy ( declaration => declaration . ParentDeclaration )
66
- . ToDictionary ( grouping => grouping . Key , grouping => grouping . ToArray ( ) ) ) ;
67
- _userDeclarationsByType = new ConcurrentDictionary < DeclarationType , Declaration [ ] > (
68
- declarations . Where ( declaration => ! declaration . IsBuiltIn )
69
- . GroupBy ( declaration => declaration . DeclarationType )
70
- . ToDictionary ( grouping => grouping . Key , grouping => grouping . ToArray ( ) ) ) ;
60
+ _annotations = annotations . GroupBy ( node => node . QualifiedSelection . QualifiedName ) . ToConcurrentDictionary ( ) ;
61
+ _declarations = declarations . GroupBy ( item => item . QualifiedName . QualifiedModuleName ) . ToConcurrentDictionary ( ) ;
62
+ _declarationsByName = declarations . GroupBy ( declaration => declaration . IdentifierName . ToLowerInvariant ( ) ) . ToConcurrentDictionary ( ) ;
63
+ _parametersByParent = declarations . Where ( declaration => declaration . DeclarationType == DeclarationType . Parameter )
64
+ . GroupBy ( declaration => declaration . ParentDeclaration ) . ToConcurrentDictionary ( ) ;
65
+ _userDeclarationsByType = declarations . Where ( declaration => ! declaration . IsBuiltIn ) . GroupBy ( declaration => declaration . DeclarationType ) . ToConcurrentDictionary ( ) ;
71
66
_builtinEvents = new Lazy < ConcurrentBag < Declaration > > ( ( ) => FindBuiltInEventHandlers ( declarations ) ) ;
72
67
73
- _projects = _projects = declarations . Where ( d => d . DeclarationType == DeclarationType . Project ) . ToList ( ) ;
74
- _classes = _declarations . AllValues ( ) . Where ( d => d . DeclarationType == DeclarationType . ClassModule ) . ToList ( ) ;
68
+ _projects = _projects = new Lazy < ConcurrentBag < Declaration > > ( ( ) => new ConcurrentBag < Declaration > ( declarations . Where ( d => d . DeclarationType == DeclarationType . Project ) ) ) ;
69
+ _classes = new Lazy < ConcurrentBag < Declaration > > ( ( ) => new ConcurrentBag < Declaration > ( declarations . Where ( d => d . DeclarationType == DeclarationType . ClassModule ) ) ) ;
75
70
76
71
var withEventsFields = UserDeclarations ( DeclarationType . Variable ) . Where ( item => item . IsWithEvents ) . ToArray ( ) ;
77
72
var events = withEventsFields . Select ( field =>
@@ -95,7 +90,7 @@ public DeclarationFinder(IReadOnlyList<Declaration> declarations, IEnumerable<IA
95
90
. ToDictionary ( item => item . WithEventsField , item => item . Handlers . ToArray ( ) )
96
91
) ) ;
97
92
98
- _undeclared = new ConcurrentDictionary < QualifiedMemberName , IList < Declaration > > ( new Dictionary < QualifiedMemberName , IList < Declaration > > ( ) ) ;
93
+ _undeclared = new ConcurrentDictionary < QualifiedMemberName , ConcurrentBag < Declaration > > ( new Dictionary < QualifiedMemberName , ConcurrentBag < Declaration > > ( ) ) ;
99
94
_unresolved = new ConcurrentBag < UnboundMemberDeclaration > ( new List < UnboundMemberDeclaration > ( ) ) ;
100
95
_annotationService = new AnnotationService ( this ) ;
101
96
@@ -111,7 +106,7 @@ public DeclarationFinder(IReadOnlyList<Declaration> declarations, IEnumerable<IA
111
106
} ) ;
112
107
113
108
_interfaceMembers = new Lazy < ConcurrentDictionary < Declaration , Declaration [ ] > > ( ( ) =>
114
- new ConcurrentDictionary < Declaration , Declaration [ ] > ( interfaceMembers . ToDictionary ( item => item . InterfaceModule , item => item . InterfaceMembers . ToArray ( ) ) ) ) ;
109
+ new ConcurrentDictionary < Declaration , Declaration [ ] > ( interfaceMembers . ToDictionary ( item => item . InterfaceModule , item => item . InterfaceMembers . ToArray ( ) ) ) ) ;
115
110
116
111
var implementingNames = new Lazy < IEnumerable < string > > ( ( ) => implementsInstructions . SelectMany ( item =>
117
112
_declarations [ item . IdentifierReference . Declaration . QualifiedName . QualifiedModuleName ]
@@ -158,21 +153,40 @@ public IEnumerable<Declaration> FindBuiltinEventHandlers()
158
153
}
159
154
}
160
155
161
- private readonly IEnumerable < Declaration > _classes ;
162
- public IEnumerable < Declaration > Classes { get { return _classes ; } }
156
+ private readonly Lazy < ConcurrentBag < Declaration > > _classes ;
157
+
158
+ public IEnumerable < Declaration > Classes
159
+ {
160
+ get
161
+ {
162
+ lock ( ThreadLock )
163
+ {
164
+ return _classes . Value ;
165
+ }
166
+ }
167
+ }
168
+
169
+ private readonly Lazy < ConcurrentBag < Declaration > > _projects ;
163
170
164
- private readonly IEnumerable < Declaration > _projects ;
165
- public IEnumerable < Declaration > Projects { get { return _projects ; } }
171
+ public IEnumerable < Declaration > Projects
172
+ {
173
+ get
174
+ {
175
+ lock ( ThreadLock )
176
+ {
177
+ return _projects . Value ;
178
+ }
179
+ }
180
+ }
166
181
167
182
public IEnumerable < Declaration > UserDeclarations ( DeclarationType type )
168
183
{
169
- Declaration [ ] result ;
184
+ ConcurrentBag < Declaration > result ;
170
185
if ( ! _userDeclarationsByType . TryGetValue ( type , out result ) )
171
186
{
172
- result = _userDeclarationsByType
187
+ result = new ConcurrentBag < Declaration > ( _userDeclarationsByType
173
188
. Where ( item => item . Key . HasFlag ( type ) )
174
- . SelectMany ( item => item . Value )
175
- . ToArray ( ) ;
189
+ . SelectMany ( item => item . Value ) ) ;
176
190
}
177
191
return result ;
178
192
}
@@ -218,7 +232,7 @@ public Declaration FindParameter(Declaration procedure, string parameterName)
218
232
219
233
public IEnumerable < Declaration > FindMemberMatches ( Declaration parent , string memberName )
220
234
{
221
- Declaration [ ] children ;
235
+ ConcurrentBag < Declaration > children ;
222
236
if ( _declarations . TryGetValue ( parent . QualifiedName . QualifiedModuleName , out children ) )
223
237
{
224
238
return children . Where ( item => item . DeclarationType . HasFlag ( DeclarationType . Member )
@@ -230,7 +244,7 @@ public IEnumerable<Declaration> FindMemberMatches(Declaration parent, string mem
230
244
231
245
public IEnumerable < IAnnotation > FindAnnotations ( QualifiedModuleName module )
232
246
{
233
- IAnnotation [ ] result ;
247
+ ConcurrentBag < IAnnotation > result ;
234
248
return _annotations . TryGetValue ( module , out result ) ? result : Enumerable . Empty < IAnnotation > ( ) ;
235
249
}
236
250
@@ -264,7 +278,7 @@ public Declaration FindLabel(Declaration procedure, string label)
264
278
public IEnumerable < Declaration > MatchName ( string name )
265
279
{
266
280
var normalizedName = ToNormalizedName ( name ) ;
267
- Declaration [ ] result ;
281
+ ConcurrentBag < Declaration > result ;
268
282
return _declarationsByName . TryGetValue ( normalizedName , out result )
269
283
? result
270
284
: Enumerable . Empty < Declaration > ( ) ;
@@ -305,7 +319,7 @@ public Declaration FindStdModule(string name, Declaration parent = null, bool in
305
319
{
306
320
var matches = MatchName ( name ) ;
307
321
result = matches . SingleOrDefault ( declaration => declaration . DeclarationType . HasFlag ( DeclarationType . ProceduralModule )
308
- && ( parent == null || parent . Equals ( declaration . ParentDeclaration ) )
322
+ && ( parent . Equals ( declaration . ParentDeclaration ) )
309
323
&& ( includeBuiltIn || ! declaration . IsBuiltIn ) ) ;
310
324
}
311
325
catch ( InvalidOperationException exception )
@@ -324,7 +338,7 @@ public Declaration FindClassModule(string name, Declaration parent = null, bool
324
338
{
325
339
var matches = MatchName ( name ) ;
326
340
result = matches . SingleOrDefault ( declaration => declaration . DeclarationType . HasFlag ( DeclarationType . ClassModule )
327
- && ( parent == null || parent . Equals ( declaration . ParentDeclaration ) )
341
+ && ( parent . Equals ( declaration . ParentDeclaration ) )
328
342
&& ( includeBuiltIn || ! declaration . IsBuiltIn ) ) ;
329
343
}
330
344
catch ( InvalidOperationException exception )
@@ -481,18 +495,22 @@ public Declaration OnUndeclaredVariable(Declaration enclosingProcedure, string i
481
495
var hasUndeclared = _undeclared . ContainsKey ( enclosingProcedure . QualifiedName ) ;
482
496
if ( hasUndeclared )
483
497
{
484
- var inScopeUndeclared = _undeclared [ enclosingProcedure . QualifiedName ] . FirstOrDefault ( d => d . IdentifierName == identifierName ) ;
498
+ ConcurrentBag < Declaration > undeclared ;
499
+ while ( ! _undeclared . TryGetValue ( enclosingProcedure . QualifiedName , out undeclared ) )
500
+ {
501
+ _undeclared . TryGetValue ( enclosingProcedure . QualifiedName , out undeclared ) ;
502
+ }
503
+ var inScopeUndeclared = undeclared . FirstOrDefault ( d => d . IdentifierName == identifierName ) ;
485
504
if ( inScopeUndeclared != null )
486
505
{
487
506
return inScopeUndeclared ;
488
507
}
489
- _undeclared [ enclosingProcedure . QualifiedName ] . Add ( undeclaredLocal ) ;
508
+ undeclared . Add ( undeclaredLocal ) ;
490
509
}
491
510
else
492
511
{
493
- _undeclared [ enclosingProcedure . QualifiedName ] = new List < Declaration > { undeclaredLocal } ;
512
+ _undeclared . TryAdd ( enclosingProcedure . QualifiedName , new ConcurrentBag < Declaration > { undeclaredLocal } ) ;
494
513
}
495
-
496
514
return undeclaredLocal ;
497
515
}
498
516
@@ -524,14 +542,14 @@ public Declaration OnBracketedExpression(string expression, ParserRuleContext co
524
542
525
543
var qualifiedName = hostApp . QualifiedName . QualifiedModuleName . QualifyMemberName ( expression ) ;
526
544
527
- IList < Declaration > undeclared ;
545
+ ConcurrentBag < Declaration > undeclared ;
528
546
if ( _undeclared . TryGetValue ( qualifiedName , out undeclared ) )
529
547
{
530
548
return undeclared . SingleOrDefault ( ) ;
531
549
}
532
550
533
551
var item = new Declaration ( qualifiedName , hostApp , hostApp , Tokens . Variant , string . Empty , false , false , Accessibility . Global , DeclarationType . BracketedExpression , context , context . GetSelection ( ) , false , null ) ;
534
- _undeclared . TryAdd ( qualifiedName , new List < Declaration > { item } ) ;
552
+ _undeclared . TryAdd ( qualifiedName , new ConcurrentBag < Declaration > { item } ) ;
535
553
return item ;
536
554
}
537
555
0 commit comments