@@ -33,7 +33,8 @@ public IdentifierReferenceListener(QualifiedModuleName qualifiedModuleName, Decl
33
33
_moduleTypes = new HashSet < DeclarationType > ( new [ ]
34
34
{
35
35
DeclarationType . Module ,
36
- DeclarationType . Class
36
+ DeclarationType . Class ,
37
+ DeclarationType . Project
37
38
} ) ;
38
39
39
40
_memberTypes = new HashSet < DeclarationType > ( new [ ]
@@ -154,7 +155,8 @@ public override void EnterWithStmt(VBAParser.WithStmtContext context)
154
155
{
155
156
// object variable is a built-in Collection class instance
156
157
qualifier = _declarations . Items . Single ( item => item . IsBuiltIn
157
- && item . IdentifierName == collectionContext . GetText ( ) ) ;
158
+ && item . IdentifierName == collectionContext . GetText ( )
159
+ && item . DeclarationType == DeclarationType . Class ) ;
158
160
reference = CreateReference ( baseTypeContext , qualifier ) ;
159
161
}
160
162
}
@@ -206,7 +208,7 @@ private Declaration ResolveType(VBAParser.ComplexTypeContext context)
206
208
{
207
209
return _declarations [ identifier . GetText ( ) ] . SingleOrDefault ( item =>
208
210
item . ProjectName == libraryName
209
- && item . DeclarationType == DeclarationType . Class ) ;
211
+ && _moduleTypes . Contains ( item . DeclarationType ) ) ;
210
212
}
211
213
212
214
return null ;
@@ -244,13 +246,15 @@ private Declaration ResolveType(Declaration parent)
244
246
// look in current project first.
245
247
var result = _declarations [ parent . AsTypeName ] . SingleOrDefault ( item =>
246
248
_moduleTypes . Contains ( item . DeclarationType )
247
- && item . ProjectName == _currentScope . ProjectName ) ;
249
+ && item . ProjectName == _currentScope . ProjectName
250
+ && _moduleTypes . Contains ( item . DeclarationType ) ) ;
248
251
249
252
if ( result == null )
250
253
{
251
- // look in all projects (including VbaStdLib library.
254
+ // look in all projects (including VbaStdLib library) .
252
255
result = _declarations [ parent . AsTypeName ] . SingleOrDefault ( item =>
253
- _moduleTypes . Contains ( item . DeclarationType ) ) ;
256
+ _moduleTypes . Contains ( item . DeclarationType )
257
+ && _moduleTypes . Contains ( item . DeclarationType ) ) ;
254
258
}
255
259
256
260
return result ;
@@ -298,6 +302,17 @@ private Declaration Resolve(ParserRuleContext callSiteContext, Declaration local
298
302
?? FindModuleScopeProcedure ( identifierName , localScope , accessorType )
299
303
?? FindProjectScopeDeclaration ( identifierName ) ;
300
304
305
+ if ( callee == null )
306
+ {
307
+ // calls inside With block can still refer to identifiers in _currentScope
308
+ localScope = _currentScope ;
309
+ identifierName = callSiteContext . GetText ( ) ;
310
+ callee = FindLocalScopeDeclaration ( identifierName , localScope )
311
+ ?? FindModuleScopeDeclaration ( identifierName , localScope )
312
+ ?? FindModuleScopeProcedure ( identifierName , localScope , accessorType )
313
+ ?? FindProjectScopeDeclaration ( identifierName ) ;
314
+ }
315
+
301
316
if ( callee == null )
302
317
{
303
318
return null ;
@@ -321,8 +336,6 @@ private Declaration Resolve(VBAParser.ICS_S_VariableOrProcedureCallContext conte
321
336
return null ;
322
337
}
323
338
324
- _isResolving = true ;
325
-
326
339
var identifierContext = context . ambiguousIdentifier ( ) ;
327
340
var fieldCall = context . dictionaryCallStmt ( ) ;
328
341
@@ -360,8 +373,6 @@ private Declaration Resolve(VBAParser.ICS_S_ProcedureOrArrayCallContext context,
360
373
return null ;
361
374
}
362
375
363
- _isResolving = true ;
364
-
365
376
var identifierContext = context . ambiguousIdentifier ( ) ;
366
377
var fieldCall = context . dictionaryCallStmt ( ) ;
367
378
// todo: understand WTF [baseType] is doing in that grammar rule...
@@ -376,8 +387,6 @@ private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context, ContextA
376
387
return null ;
377
388
}
378
389
379
- _isResolving = true ;
380
-
381
390
if ( localScope == null )
382
391
{
383
392
localScope = _currentScope ;
@@ -403,8 +412,6 @@ private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context, ContextA
403
412
return null ;
404
413
}
405
414
406
- //var memberReference = CreateReference(member.Context, member);
407
- //member.AddReference(memberReference);
408
415
parent = member ;
409
416
}
410
417
@@ -417,24 +424,24 @@ private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context, ContextA
417
424
return Resolve ( fieldCall , parent , hasExplicitLetStatement , isAssignmentTarget ) ;
418
425
}
419
426
420
- private void Resolve ( VBAParser . ICS_B_ProcedureCallContext context )
427
+ private Declaration Resolve ( VBAParser . ICS_B_ProcedureCallContext context )
421
428
{
422
429
if ( context == null )
423
430
{
424
- return ;
431
+ return null ;
425
432
}
426
433
427
- _isResolving = true ;
428
-
429
434
var identifierContext = context . certainIdentifier ( ) ;
430
435
var callee = Resolve ( identifierContext , _currentScope ) ;
431
436
if ( callee == null )
432
437
{
433
- return ;
438
+ return null ;
434
439
}
435
440
436
441
var reference = CreateReference ( identifierContext , callee ) ;
437
442
callee . AddReference ( reference ) ;
443
+
444
+ return callee ;
438
445
}
439
446
440
447
private Declaration Resolve ( VBAParser . ImplicitCallStmt_InStmtContext callSiteContext , Declaration localScope , ContextAccessorType accessorType , bool hasExplicitLetStatement = false , bool isAssignmentTarget = false )
@@ -471,7 +478,8 @@ private Declaration FindLocalScopeDeclaration(string identifierName, Declaration
471
478
}
472
479
473
480
var parent = _declarations [ identifierName ] . SingleOrDefault ( item =>
474
- item . ParentScope == localScope . Scope ) ;
481
+ item . ParentScope == localScope . Scope
482
+ && ! _moduleTypes . Contains ( item . DeclarationType ) ) ;
475
483
return parent ;
476
484
}
477
485
@@ -490,7 +498,8 @@ private Declaration FindModuleScopeDeclaration(string identifierName, Declaratio
490
498
491
499
return _declarations [ identifierName ] . SingleOrDefault ( item =>
492
500
item . ParentScope == localScope . ParentScope
493
- && ! item . DeclarationType . HasFlag ( DeclarationType . Member ) ) ;
501
+ && ! item . DeclarationType . HasFlag ( DeclarationType . Member )
502
+ && ! _moduleTypes . Contains ( item . DeclarationType ) ) ;
494
503
}
495
504
496
505
/// <summary>
@@ -529,8 +538,9 @@ private Declaration FindProjectScopeDeclaration(string identifierName)
529
538
{
530
539
// assume unqualified variable call, i.e. unique declaration.
531
540
return _declarations [ identifierName ] . SingleOrDefault ( item =>
532
- item . Accessibility == Accessibility . Public
533
- || item . Accessibility == Accessibility . Global ) ;
541
+ ( item . Accessibility == Accessibility . Public
542
+ || item . Accessibility == Accessibility . Global
543
+ || item . DeclarationType == DeclarationType . Module ) ) ;
534
544
}
535
545
536
546
/// <summary>
@@ -551,29 +561,13 @@ private Declaration FindProjectScopeDeclaration(string identifierName, string mo
551
561
552
562
#region IVBAListener overrides
553
563
554
- // avoid re-resolving identifiers
555
- private bool _isResolving ;
556
-
557
564
public override void EnterICS_B_ProcedureCall ( VBAParser . ICS_B_ProcedureCallContext context )
558
565
{
559
- if ( _isResolving )
560
- {
561
- return ;
562
- }
563
-
564
566
Resolve ( context ) ;
565
- _isResolving = false ;
566
567
}
567
568
568
569
public override void EnterICS_B_MemberProcedureCall ( VBAParser . ICS_B_MemberProcedureCallContext context )
569
570
{
570
- if ( _isResolving )
571
- {
572
- return ;
573
- }
574
-
575
- _isResolving = true ;
576
-
577
571
var parentScope = Resolve ( context . implicitCallStmt_InStmt ( ) , _currentScope , ContextAccessorType . GetValueOrReference ) ;
578
572
var parentType = ResolveType ( parentScope ) ;
579
573
@@ -600,47 +594,25 @@ public override void EnterICS_B_MemberProcedureCall(VBAParser.ICS_B_MemberProced
600
594
601
595
var fieldCall = context . dictionaryCallStmt ( ) ;
602
596
Resolve ( fieldCall , member ) ;
603
-
604
- _isResolving = false ;
605
597
}
606
598
607
599
public override void EnterICS_S_VariableOrProcedureCall ( VBAParser . ICS_S_VariableOrProcedureCallContext context )
608
600
{
609
- if ( _isResolving )
610
- {
611
- return ;
612
- }
613
-
614
601
Resolve ( context , _currentScope ) ;
615
602
}
616
603
617
604
public override void EnterICS_S_ProcedureOrArrayCall ( VBAParser . ICS_S_ProcedureOrArrayCallContext context )
618
605
{
619
- if ( _isResolving )
620
- {
621
- return ;
622
- }
623
-
624
606
Resolve ( context , _currentScope ) ;
625
607
}
626
608
627
609
public override void EnterICS_S_MembersCall ( VBAParser . ICS_S_MembersCallContext context )
628
610
{
629
- if ( _isResolving )
630
- {
631
- return ;
632
- }
633
-
634
611
Resolve ( context , _currentScope ) ;
635
612
}
636
613
637
614
public override void EnterICS_S_DictionaryCall ( VBAParser . ICS_S_DictionaryCallContext context )
638
615
{
639
- if ( _isResolving )
640
- {
641
- return ;
642
- }
643
-
644
616
Resolve ( context , _currentScope ) ;
645
617
}
646
618
@@ -674,7 +646,7 @@ public override void EnterAsTypeClause(VBAParser.AsTypeClauseContext context)
674
646
var collection = baseType . COLLECTION ( ) ;
675
647
if ( collection != null )
676
648
{
677
- type = _declarations [ collection . GetText ( ) ] . SingleOrDefault ( item => item . IsBuiltIn ) ;
649
+ type = _declarations [ collection . GetText ( ) ] . SingleOrDefault ( item => item . IsBuiltIn && item . DeclarationType == DeclarationType . Class ) ;
678
650
reference = CreateReference ( baseType , type ) ;
679
651
}
680
652
}
@@ -695,6 +667,7 @@ public override void EnterForNextStmt(VBAParser.ForNextStmtContext context)
695
667
var identifiers = context . ambiguousIdentifier ( ) ;
696
668
var identifier = Resolve ( identifiers [ 0 ] , _currentScope , ContextAccessorType . AssignValue ) ;
697
669
670
+ // each iteration counts as an assignment
698
671
var reference = CreateReference ( identifiers [ 0 ] , identifier , true ) ;
699
672
identifier . AddReference ( reference ) ;
700
673
@@ -704,6 +677,91 @@ public override void EnterForNextStmt(VBAParser.ForNextStmtContext context)
704
677
}
705
678
}
706
679
680
+ public override void EnterForEachStmt ( VBAParser . ForEachStmtContext context )
681
+ {
682
+ var identifiers = context . ambiguousIdentifier ( ) ;
683
+ var identifier = Resolve ( identifiers [ 0 ] , _currentScope ) ;
684
+
685
+ // each iteration counts as an assignment
686
+ var reference = CreateReference ( identifiers [ 0 ] , identifier , true ) ;
687
+ identifier . AddReference ( reference ) ;
688
+
689
+ if ( identifiers . Count > 1 )
690
+ {
691
+ identifier . AddReference ( CreateReference ( identifiers [ 1 ] , identifier ) ) ;
692
+ }
693
+ }
694
+
695
+ public override void EnterImplementsStmt ( VBAParser . ImplementsStmtContext context )
696
+ {
697
+ var identifierContext = context . ambiguousIdentifier ( ) ;
698
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
699
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
700
+ }
701
+
702
+ public override void EnterRaiseEventStmt ( VBAParser . RaiseEventStmtContext context )
703
+ {
704
+ var identifierContext = context . ambiguousIdentifier ( ) ;
705
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
706
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
707
+ }
708
+
709
+ public override void EnterResumeStmt ( VBAParser . ResumeStmtContext context )
710
+ {
711
+ var identifierContext = context . ambiguousIdentifier ( ) ;
712
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
713
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
714
+ }
715
+
716
+ public override void EnterFileNumber ( VBAParser . FileNumberContext context )
717
+ {
718
+ var identifierContext = context . ambiguousIdentifier ( ) ;
719
+ if ( identifierContext == null )
720
+ {
721
+ return ;
722
+ }
723
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
724
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
725
+ }
726
+
727
+ public override void EnterArgDefaultValue ( VBAParser . ArgDefaultValueContext context )
728
+ {
729
+ var identifierContext = context . ambiguousIdentifier ( ) ;
730
+ if ( identifierContext == null )
731
+ {
732
+ return ;
733
+ }
734
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
735
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
736
+ }
737
+
738
+ public override void EnterFieldLength ( VBAParser . FieldLengthContext context )
739
+ {
740
+ var identifierContext = context . ambiguousIdentifier ( ) ;
741
+ if ( identifierContext == null )
742
+ {
743
+ return ;
744
+ }
745
+ var identifier = Resolve ( identifierContext , _currentScope ) ;
746
+ identifier . AddReference ( CreateReference ( identifierContext , identifier ) ) ;
747
+ }
748
+
749
+ public override void EnterVsAssign ( VBAParser . VsAssignContext context )
750
+ {
751
+ // named parameter reference must be scoped to called procedure
752
+ var callee = FindParentCall ( context ) ;
753
+ Resolve ( context . implicitCallStmt_InStmt ( ) , callee ) ;
754
+ }
755
+
756
+ private Declaration FindParentCall ( VBAParser . VsAssignContext context )
757
+ {
758
+ var calleeContext = context . Parent . Parent . Parent ;
759
+ return Resolve ( calleeContext as VBAParser . ICS_B_ProcedureCallContext )
760
+ ?? Resolve ( calleeContext as VBAParser . ICS_S_VariableOrProcedureCallContext , _currentScope )
761
+ ?? Resolve ( calleeContext as VBAParser . ICS_S_ProcedureOrArrayCallContext , _currentScope )
762
+ ?? Resolve ( calleeContext as VBAParser . ICS_S_MembersCallContext , _currentScope ) ;
763
+ }
764
+
707
765
#endregion
708
766
709
767
private IdentifierReference CreateReference ( ParserRuleContext callSiteContext , Declaration callee , bool isAssignmentTarget = false , bool hasExplicitLetStatement = false )
0 commit comments