@@ -52,8 +52,11 @@ public class DeclarationFinder
52
52
private readonly Lazy < ConcurrentDictionary < Declaration , Declaration [ ] > > _handlersByWithEventsField ;
53
53
private readonly Lazy < ConcurrentDictionary < VBAParser . ImplementsStmtContext , Declaration [ ] > > _membersByImplementsContext ;
54
54
private readonly Lazy < ConcurrentDictionary < Declaration , Declaration [ ] > > _interfaceMembers ;
55
+ private Lazy < List < Declaration > > _nonBaseAsType ;
56
+ private readonly Lazy < ConcurrentBag < Declaration > > _eventHandlers ;
57
+ private readonly Lazy < ConcurrentBag < Declaration > > _classes ;
55
58
56
- private static readonly object ThreadLock = new object ( ) ;
59
+ private readonly object threadLock = new object ( ) ;
57
60
58
61
public DeclarationFinder ( IReadOnlyList < Declaration > declarations , IEnumerable < IAnnotation > annotations , IReadOnlyList < UnboundMemberDeclaration > unresolvedMemberDeclarations , IHostApplication hostApp = null )
59
62
{
@@ -133,8 +136,16 @@ public DeclarationFinder(IReadOnlyList<Declaration> declarations, IEnumerable<IA
133
136
} ) ;
134
137
135
138
_membersByImplementsContext = new Lazy < ConcurrentDictionary < VBAParser . ImplementsStmtContext , Declaration [ ] > > ( ( ) =>
136
- new ConcurrentDictionary < VBAParser . ImplementsStmtContext , Declaration [ ] > (
137
- implementableMembers . ToDictionary ( item => item . Context , item => item . Members ) ) , true ) ;
139
+ new ConcurrentDictionary < VBAParser . ImplementsStmtContext , Declaration [ ] > (
140
+ implementableMembers . ToDictionary ( item => item . Context , item => item . Members ) ) , true ) ;
141
+
142
+ _nonBaseAsType = new Lazy < List < Declaration > > ( ( ) =>
143
+ _declarations . AllValues ( ) . Where ( d =>
144
+ ! string . IsNullOrWhiteSpace ( d . AsTypeName )
145
+ && ! d . AsTypeIsBaseType
146
+ && d . DeclarationType != DeclarationType . Project
147
+ && d . DeclarationType != DeclarationType . ProceduralModule ) . ToList ( )
148
+ , true ) ;
138
149
}
139
150
140
151
public IEnumerable < Declaration > FreshUndeclared
@@ -152,38 +163,22 @@ public IEnumerable<Declaration> Members(QualifiedModuleName module)
152
163
return _declarations [ module ] ;
153
164
}
154
165
155
- private IEnumerable < Declaration > _nonBaseAsType ;
156
166
public IEnumerable < Declaration > FindDeclarationsWithNonBaseAsType ( )
157
167
{
158
- lock ( ThreadLock )
159
- {
160
- return _nonBaseAsType ?? ( _nonBaseAsType = _declarations . AllValues ( ) . Where ( d =>
161
- ! string . IsNullOrWhiteSpace ( d . AsTypeName )
162
- && ! d . AsTypeIsBaseType
163
- && d . DeclarationType != DeclarationType . Project
164
- && d . DeclarationType != DeclarationType . ProceduralModule ) . ToList ( ) ) ;
165
- }
166
- }
168
+ return _nonBaseAsType . Value ;
167
169
168
- private readonly Lazy < ConcurrentBag < Declaration > > _eventHandlers ;
170
+ }
171
+
169
172
public IEnumerable < Declaration > FindEventHandlers ( )
170
173
{
171
- lock ( ThreadLock )
172
- {
173
- return _eventHandlers . Value ;
174
- }
174
+ return _eventHandlers . Value ;
175
175
}
176
176
177
- private readonly Lazy < ConcurrentBag < Declaration > > _classes ;
178
-
179
177
public IEnumerable < Declaration > Classes
180
178
{
181
179
get
182
180
{
183
- lock ( ThreadLock )
184
- {
185
- return _classes . Value ;
186
- }
181
+ return _classes . Value ;
187
182
}
188
183
}
189
184
@@ -193,10 +188,7 @@ public IEnumerable<Declaration> Projects
193
188
{
194
189
get
195
190
{
196
- lock ( ThreadLock )
197
- {
198
- return _projects . Value ;
199
- }
191
+ return _projects . Value ;
200
192
}
201
193
}
202
194
@@ -214,10 +206,7 @@ public IEnumerable<Declaration> UserDeclarations(DeclarationType type)
214
206
215
207
public IEnumerable < UnboundMemberDeclaration > FreshUnresolvedMemberDeclarations ( )
216
208
{
217
- lock ( ThreadLock )
218
- {
219
- return _newUnresolved . ToArray ( ) ;
220
- }
209
+ return _newUnresolved . ToArray ( ) ; //This does not need a lock because enumerators over a ConcurrentBag uses a snapshot.
221
210
}
222
211
223
212
public IEnumerable < UnboundMemberDeclaration > UnresolvedMemberDeclarations ( )
@@ -253,25 +242,27 @@ public IEnumerable<Declaration> FindAllInterfaceImplementingMembers()
253
242
254
243
public Declaration FindParameter ( Declaration procedure , string parameterName )
255
244
{
256
- return _parametersByParent [ procedure ] . SingleOrDefault ( parameter => parameter . IdentifierName == parameterName ) ;
245
+ ConcurrentBag < Declaration > parameters ;
246
+ return _parametersByParent . TryGetValue ( procedure , out parameters )
247
+ ? parameters . SingleOrDefault ( parameter => parameter . IdentifierName == parameterName )
248
+ : null ;
257
249
}
258
250
259
251
public IEnumerable < Declaration > FindMemberMatches ( Declaration parent , string memberName )
260
252
{
261
253
ConcurrentBag < Declaration > children ;
262
- if ( _declarations . TryGetValue ( parent . QualifiedName . QualifiedModuleName , out children ) )
263
- {
264
- return children . Where ( item => item . DeclarationType . HasFlag ( DeclarationType . Member )
265
- && item . IdentifierName == memberName ) . ToList ( ) ;
266
- }
267
-
268
- return Enumerable . Empty < Declaration > ( ) ;
254
+ return _declarations . TryGetValue ( parent . QualifiedName . QualifiedModuleName , out children )
255
+ ? children . Where ( item => item . DeclarationType . HasFlag ( DeclarationType . Member )
256
+ && item . IdentifierName == memberName ) . ToList ( )
257
+ : Enumerable . Empty < Declaration > ( ) ;
269
258
}
270
259
271
260
public IEnumerable < IAnnotation > FindAnnotations ( QualifiedModuleName module )
272
261
{
273
262
ConcurrentBag < IAnnotation > result ;
274
- return _annotations . TryGetValue ( module , out result ) ? result : Enumerable . Empty < IAnnotation > ( ) ;
263
+ return _annotations . TryGetValue ( module , out result )
264
+ ? result
265
+ : Enumerable . Empty < IAnnotation > ( ) ;
275
266
}
276
267
277
268
public bool IsMatch ( string declarationName , string potentialMatchName )
@@ -326,7 +317,8 @@ public Declaration FindProject(string name, Declaration currentScope = null)
326
317
Declaration result = null ;
327
318
try
328
319
{
329
- result = MatchName ( name ) . SingleOrDefault ( project => project . DeclarationType . HasFlag ( DeclarationType . Project )
320
+ result = MatchName ( name ) . SingleOrDefault ( project =>
321
+ project . DeclarationType . HasFlag ( DeclarationType . Project )
330
322
&& ( currentScope == null || project . ProjectId == currentScope . ProjectId ) ) ;
331
323
}
332
324
catch ( InvalidOperationException exception )
@@ -337,7 +329,7 @@ public Declaration FindProject(string name, Declaration currentScope = null)
337
329
return result ;
338
330
}
339
331
340
- public Declaration FindStdModule ( string name , Declaration parent = null , bool includeBuiltIn = false )
332
+ public Declaration FindStdModule ( string name , Declaration parent , bool includeBuiltIn = false )
341
333
{
342
334
Debug . Assert ( parent != null ) ;
343
335
Declaration result = null ;
@@ -356,7 +348,7 @@ public Declaration FindStdModule(string name, Declaration parent = null, bool in
356
348
return result ;
357
349
}
358
350
359
- public Declaration FindClassModule ( string name , Declaration parent = null , bool includeBuiltIn = false )
351
+ public Declaration FindClassModule ( string name , Declaration parent , bool includeBuiltIn = false )
360
352
{
361
353
Debug . Assert ( parent != null ) ;
362
354
Declaration result = null ;
0 commit comments