@@ -165,7 +165,7 @@ private void ParseAll()
165
165
}
166
166
}
167
167
168
- private readonly HashSet < ReferencePriorityMap > _references = new HashSet < ReferencePriorityMap > ( ) ;
168
+ private readonly HashSet < ReferencePriorityMap > _projectReferences = new HashSet < ReferencePriorityMap > ( ) ;
169
169
170
170
private string GetReferenceProjectId ( Reference reference , IReadOnlyList < VBProject > projects )
171
171
{
@@ -197,11 +197,11 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
197
197
{
198
198
var reference = vbProject . References . Item ( priority ) ;
199
199
var referencedProjectId = GetReferenceProjectId ( reference , projects ) ;
200
- var map = _references . SingleOrDefault ( r => r . ReferencedProjectId == referencedProjectId ) ;
200
+ var map = _projectReferences . SingleOrDefault ( r => r . ReferencedProjectId == referencedProjectId ) ;
201
201
if ( map == null )
202
202
{
203
203
map = new ReferencePriorityMap ( referencedProjectId ) { { projectId , priority } } ;
204
- _references . Add ( map ) ;
204
+ _projectReferences . Add ( map ) ;
205
205
}
206
206
else
207
207
{
@@ -221,7 +221,7 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
221
221
}
222
222
}
223
223
224
- var mappedIds = _references . Select ( map => map . ReferencedProjectId ) ;
224
+ var mappedIds = _projectReferences . Select ( map => map . ReferencedProjectId ) ;
225
225
var unmapped = projects . SelectMany ( project => project . References . Cast < Reference > ( ) )
226
226
. Where ( reference => ! mappedIds . Contains ( GetReferenceProjectId ( reference , projects ) ) ) ;
227
227
foreach ( var reference in unmapped )
@@ -233,7 +233,7 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
233
233
private void UnloadComReference ( Reference reference , IReadOnlyList < VBProject > projects )
234
234
{
235
235
var referencedProjectId = GetReferenceProjectId ( reference , projects ) ;
236
- var map = _references . SingleOrDefault ( r => r . ReferencedProjectId == referencedProjectId ) ;
236
+ var map = _projectReferences . SingleOrDefault ( r => r . ReferencedProjectId == referencedProjectId ) ;
237
237
if ( map == null || ! map . IsLoaded )
238
238
{
239
239
// we're removing a reference we weren't tracking? ...this shouldn't happen.
@@ -243,7 +243,7 @@ private void UnloadComReference(Reference reference, IReadOnlyList<VBProject> pr
243
243
map . Remove ( referencedProjectId ) ;
244
244
if ( ! map . Any ( ) )
245
245
{
246
- _references . Remove ( map ) ;
246
+ _projectReferences . Remove ( map ) ;
247
247
_state . RemoveBuiltInDeclarations ( reference ) ;
248
248
}
249
249
}
@@ -338,7 +338,7 @@ private void ResolveInternal(CancellationToken token)
338
338
{
339
339
return ;
340
340
}
341
-
341
+ _projectDeclarations . Clear ( ) ;
342
342
foreach ( var kvp in _state . ParseTrees )
343
343
{
344
344
var qualifiedName = kvp . Key ;
@@ -370,6 +370,7 @@ private void ResolveInternal(CancellationToken token)
370
370
}
371
371
}
372
372
373
+ private readonly Dictionary < string , Declaration > _projectDeclarations = new Dictionary < string , Declaration > ( ) ;
373
374
private void ResolveDeclarations ( VBComponent component , IParseTree tree )
374
375
{
375
376
var qualifiedModuleName = new QualifiedModuleName ( component ) ;
@@ -392,11 +393,15 @@ private void ResolveDeclarations(VBComponent component, IParseTree tree)
392
393
_state . EmptyStringLiterals = emptyStringLiteralListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
393
394
_state . ObsoleteLetContexts = obsoleteLetStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
394
395
_state . ObsoleteCallContexts = obsoleteCallStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
395
-
396
- // cannot locate declarations in one pass *the way it's currently implemented*,
397
- // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
398
- // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
399
- var declarationsListener = new DeclarationSymbolsListener ( qualifiedModuleName , Accessibility . Implicit , component . Type , _state . GetModuleComments ( component ) , _state . GetModuleAnnotations ( component ) , _state . GetModuleAttributes ( component ) , _references ) ;
396
+ var project = component . Collection . Parent ;
397
+ var projectQualifiedName = new QualifiedModuleName ( project ) ;
398
+ Declaration projectDeclaration ;
399
+ if ( ! _projectDeclarations . TryGetValue ( projectQualifiedName . ProjectId , out projectDeclaration ) )
400
+ {
401
+ projectDeclaration = CreateProjectDeclaration ( projectQualifiedName , project ) ;
402
+ _projectDeclarations . Add ( projectQualifiedName . ProjectId , projectDeclaration ) ;
403
+ }
404
+ var declarationsListener = new DeclarationSymbolsListener ( qualifiedModuleName , Accessibility . Implicit , component . Type , _state . GetModuleComments ( component ) , _state . GetModuleAnnotations ( component ) , _state . GetModuleAttributes ( component ) , _projectReferences , projectDeclaration ) ;
400
405
// TODO: should we unify the API? consider working like the other listeners instead of event-based
401
406
declarationsListener . NewDeclaration += ( sender , e ) => _state . AddDeclaration ( e . Declaration ) ;
402
407
declarationsListener . CreateModuleDeclarations ( ) ;
@@ -408,7 +413,20 @@ private void ResolveDeclarations(VBComponent component, IParseTree tree)
408
413
Debug . Print ( "Exception thrown resolving '{0}' (thread {2}): {1}" , component . Name , exception , Thread . CurrentThread . ManagedThreadId ) ;
409
414
_state . SetModuleState ( component , ParserState . ResolverError ) ;
410
415
}
416
+ }
411
417
418
+ private Declaration CreateProjectDeclaration ( QualifiedModuleName projectQualifiedName , VBProject project )
419
+ {
420
+ var qualifiedName = projectQualifiedName . QualifyMemberName ( project . Name ) ;
421
+ var projectId = qualifiedName . QualifiedModuleName . ProjectId ;
422
+ var projectDeclaration = new ProjectDeclaration ( qualifiedName , project . Name ) ;
423
+ var references = _projectReferences . Where ( projectContainingReference => projectContainingReference . ContainsKey ( projectId ) ) ;
424
+ foreach ( var reference in references )
425
+ {
426
+ int priority = reference [ projectId ] ;
427
+ projectDeclaration . AddProjectReference ( reference . ReferencedProjectId , priority ) ;
428
+ }
429
+ return projectDeclaration ;
412
430
}
413
431
414
432
private void ResolveReferences ( DeclarationFinder finder , VBComponent component , IParseTree tree )
0 commit comments