1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
+ using System . Windows . Forms ;
4
5
using Antlr4 . Runtime ;
5
6
using Antlr4 . Runtime . Tree ;
6
7
using Rubberduck . Parsing . Grammar ;
@@ -251,6 +252,28 @@ private bool EnterIdentifier(ParserRuleContext context, Selection selection, boo
251
252
return false ;
252
253
}
253
254
255
+ public override void EnterVsNew ( VBAParser . VsNewContext context )
256
+ {
257
+ _skipIdentifiers = true ;
258
+ var identifiers = context . valueStmt ( ) . GetRuleContexts < VBAParser . ImplicitCallStmt_InStmtContext > ( ) ;
259
+
260
+ var lastIdentifier = identifiers . Last ( ) ;
261
+ var name = lastIdentifier . GetText ( ) ;
262
+
263
+ var matches = _declarations [ name ] . Where ( d => d . DeclarationType == DeclarationType . Class ) . ToList ( ) ;
264
+ var result = matches . Count <= 1
265
+ ? matches . SingleOrDefault ( )
266
+ : GetClosestScopeDeclaration ( matches , context , DeclarationType . Class ) ;
267
+
268
+ var reference = new IdentifierReference ( _qualifiedName , result . IdentifierName , lastIdentifier . GetSelection ( ) , context , result ) ;
269
+ result . AddReference ( reference ) ;
270
+ }
271
+
272
+ public override void ExitVsNew ( VBAParser . VsNewContext context )
273
+ {
274
+ _skipIdentifiers = false ;
275
+ }
276
+
254
277
private readonly Stack < Declaration > _withQualifiers = new Stack < Declaration > ( ) ;
255
278
public override void EnterWithStmt ( VBAParser . WithStmtContext context )
256
279
{
@@ -410,12 +433,6 @@ private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context)
410
433
return Resolve ( context , out discarded ) ;
411
434
}
412
435
413
- private Declaration Resolve ( VBAParser . ICS_B_ProcedureCallContext context )
414
- {
415
- var name = context . certainIdentifier ( ) . GetText ( ) ;
416
- return FindProcedureDeclaration ( name , context . certainIdentifier ( ) ) ; // note: is this a StackOverflowException waiting to bite me?
417
- }
418
-
419
436
private Declaration Resolve ( VBAParser . ICS_B_MemberProcedureCallContext context )
420
437
{
421
438
var parent = context . implicitCallStmt_InStmt ( ) ;
@@ -431,7 +448,6 @@ private Declaration Resolve(VBAParser.ICS_B_MemberProcedureCallContext context)
431
448
432
449
var type = _declarations [ parentCall . AsTypeName ] . SingleOrDefault ( item =>
433
450
item . DeclarationType == DeclarationType . Class
434
- //|| item.DeclarationType == DeclarationType.Module
435
451
|| item . DeclarationType == DeclarationType . UserDefinedType ) ;
436
452
437
453
var members = _declarations . FindMembers ( type ) ;
@@ -492,11 +508,34 @@ public override void EnterVsAssign(VBAParser.VsAssignContext context)
492
508
}
493
509
}
494
510
495
- private Declaration FindProcedureDeclaration ( string procedureName , ParserRuleContext context )
511
+ private static readonly DeclarationType [ ] PropertyAccessors =
512
+ {
513
+ DeclarationType . PropertyGet ,
514
+ DeclarationType . PropertyLet ,
515
+ DeclarationType . PropertySet
516
+ } ;
517
+
518
+ private Declaration FindProcedureDeclaration ( string procedureName , ParserRuleContext context , DeclarationType accessor = DeclarationType . PropertyGet )
496
519
{
497
520
var matches = _declarations [ procedureName ]
498
521
. Where ( declaration => ProcedureDeclarations . Contains ( declaration . DeclarationType ) )
499
- . Where ( IsInScope ) ;
522
+ . Where ( IsInScope )
523
+ . ToList ( ) ;
524
+
525
+ if ( ! matches . Any ( ) )
526
+ {
527
+ return null ;
528
+ }
529
+
530
+ if ( matches . Count == 1 )
531
+ {
532
+ return matches . First ( ) ;
533
+ }
534
+
535
+ if ( matches . All ( m => PropertyAccessors . Contains ( m . DeclarationType ) ) )
536
+ {
537
+ return matches . Find ( m => m . DeclarationType == accessor ) ;
538
+ }
500
539
501
540
var procedure = GetClosestScopeDeclaration ( matches , context ) ;
502
541
return procedure ;
@@ -567,52 +606,61 @@ private Declaration GetClosestScopeDeclaration(IEnumerable<Declaration> declarat
567
606
}
568
607
569
608
var matches = declarations as IList < Declaration > ?? declarations . ToList ( ) ;
570
- var currentScope = matches . FirstOrDefault ( declaration =>
571
- IsCurrentScopeMember ( accessorType , declaration )
572
- && ( declaration . DeclarationType == accessorType
573
- || accessorType == DeclarationType . PropertyGet ) ) ;
574
-
575
- if ( currentScope != null )
609
+ if ( ! matches . Any ( ) )
576
610
{
577
- // return currentScope ;
611
+ return null ;
578
612
}
579
613
580
- var moduleScope = matches . SingleOrDefault ( declaration => declaration . Scope == ModuleScope ) ;
581
- if ( moduleScope != null )
614
+ var currentScope = matches . SingleOrDefault ( declaration => declaration . Scope == _currentScope
615
+ && ! PropertyAccessors . Contains ( declaration . DeclarationType ) ) ;
616
+ if ( currentScope != null )
582
617
{
583
- return moduleScope ;
618
+ return currentScope ;
584
619
}
585
620
621
+ // note: commented-out because it breaks the UDT member references, but property getters behave strangely still
622
+ //var currentScope = matches.SingleOrDefault(declaration =>
623
+ // IsCurrentScopeMember(accessorType, declaration)
624
+ // && (declaration.DeclarationType == accessorType
625
+ // || accessorType == DeclarationType.PropertyGet));
626
+
627
+ //if (matches.First().IdentifierName == "procedure")
628
+ //{
629
+ // // for debugging - "procedure" is both a UDT member and a parameter to a procedure.
630
+ //}
631
+
586
632
if ( matches . Count == 1 )
587
633
{
588
634
return matches [ 0 ] ;
589
635
}
590
636
637
+ var moduleScope = matches . SingleOrDefault ( declaration => declaration . Scope == ModuleScope ) ;
638
+ if ( moduleScope != null )
639
+ {
640
+ return moduleScope ;
641
+ }
642
+
591
643
var memberProcedureCallContext = context . Parent as VBAParser . ICS_B_MemberProcedureCallContext ;
592
644
if ( memberProcedureCallContext != null )
593
645
{
594
646
return Resolve ( memberProcedureCallContext ) ;
595
- var parent = memberProcedureCallContext ;
596
- var parentMemberName = memberProcedureCallContext . ambiguousIdentifier ( ) . GetText ( ) ;
597
- var matchingParents = _declarations . Items . Where ( d => d . IdentifierName == parentMemberName
598
- && ( d . DeclarationType == DeclarationType . Class || d . DeclarationType == DeclarationType . UserDefinedType ) ) ;
599
-
600
- var parentType = _withQualifiers . Any ( )
601
- ? _withQualifiers . Peek ( )
602
- : matches . SingleOrDefault ( m =>
603
- matchingParents . Any ( p =>
604
- ( p . DeclarationType == DeclarationType . Class && m . ComponentName == p . AsTypeName )
605
- || ( p . DeclarationType == DeclarationType . UserDefinedType ) ) ) ;
647
+ }
606
648
607
- return parentType == null ? null : matches . SingleOrDefault ( m => m . ParentScope == parentType . Scope ) ;
649
+ var implicitCall = context . Parent . Parent as VBAParser . ImplicitCallStmt_InStmtContext ;
650
+ if ( implicitCall != null )
651
+ {
652
+ return Resolve ( implicitCall . iCS_S_VariableOrProcedureCall ( ) )
653
+ ?? Resolve ( implicitCall . iCS_S_ProcedureOrArrayCall ( ) )
654
+ ?? Resolve ( implicitCall . iCS_S_DictionaryCall ( ) )
655
+ ?? Resolve ( implicitCall . iCS_S_MembersCall ( ) ) ;
608
656
}
609
657
610
658
return matches . SingleOrDefault ( m => m . ParentScope == _currentScope ) ;
611
659
}
612
660
613
661
private bool IsCurrentScopeMember ( DeclarationType accessorType , Declaration declaration )
614
662
{
615
- if ( declaration . Scope != _currentScope && accessorType != DeclarationType . Class )
663
+ if ( declaration . Scope != ModuleScope && accessorType != DeclarationType . Class )
616
664
{
617
665
return false ;
618
666
}
0 commit comments