@@ -21,6 +21,9 @@ private enum ContextAccessorType
21
21
22
22
private readonly IReadOnlyList < DeclarationType > _moduleTypes ;
23
23
private readonly IReadOnlyList < DeclarationType > _memberTypes ;
24
+ private readonly IReadOnlyList < DeclarationType > _returningMemberTypes ;
25
+
26
+ private readonly IReadOnlyList < Accessibility > _projectScopePublicModifiers ;
24
27
25
28
private readonly Stack < Declaration > _withBlockQualifiers ;
26
29
private readonly HashSet < RuleContext > _alreadyResolved ;
@@ -37,7 +40,7 @@ public IdentifierReferenceResolver(QualifiedModuleName qualifiedModuleName, Decl
37
40
{
38
41
DeclarationType . Module ,
39
42
DeclarationType . Class ,
40
- DeclarationType . Project
43
+ DeclarationType . Project ,
41
44
} ) ;
42
45
43
46
_memberTypes = new List < DeclarationType > ( new [ ]
@@ -46,7 +49,21 @@ public IdentifierReferenceResolver(QualifiedModuleName qualifiedModuleName, Decl
46
49
DeclarationType . Procedure ,
47
50
DeclarationType . PropertyGet ,
48
51
DeclarationType . PropertyLet ,
49
- DeclarationType . PropertySet
52
+ DeclarationType . PropertySet ,
53
+ } ) ;
54
+
55
+ _returningMemberTypes = new List < DeclarationType > ( new [ ]
56
+ {
57
+ DeclarationType . Function ,
58
+ DeclarationType . PropertyGet ,
59
+ } ) ;
60
+
61
+ _projectScopePublicModifiers = new List < Accessibility > ( new [ ]
62
+ {
63
+ Accessibility . Public ,
64
+ Accessibility . Global ,
65
+ Accessibility . Friend ,
66
+ Accessibility . Implicit ,
50
67
} ) ;
51
68
52
69
SetCurrentScope ( ) ;
@@ -161,10 +178,7 @@ private Declaration ResolveType(VBAParser.ComplexTypeContext context)
161
178
{
162
179
return matches . SingleOrDefault ( item =>
163
180
item . ProjectName == libraryName
164
- && ( item . Accessibility == Accessibility . Public
165
- || item . Accessibility == Accessibility . Global
166
- || item . Accessibility == Accessibility . Friend
167
- || item . Accessibility == Accessibility . Implicit )
181
+ && _projectScopePublicModifiers . Contains ( item . Accessibility )
168
182
&& ( _moduleTypes . Contains ( item . DeclarationType ) )
169
183
|| ( item . DeclarationType == DeclarationType . UserDefinedType
170
184
&& item . ComponentName == _currentScope . ComponentName ) ) ;
@@ -229,6 +243,7 @@ private Declaration ResolveInternal(ParserRuleContext callSiteContext, Declarati
229
243
localScope = _currentScope ;
230
244
}
231
245
246
+ var parentContext = callSiteContext . Parent ;
232
247
var identifierName = callSiteContext . GetText ( ) ;
233
248
Declaration callee = null ;
234
249
if ( localScope . DeclarationType == DeclarationType . Variable )
@@ -242,18 +257,18 @@ private Declaration ResolveInternal(ParserRuleContext callSiteContext, Declarati
242
257
}
243
258
else
244
259
{
245
- callee = FindLocalScopeDeclaration ( identifierName , localScope )
246
- ?? FindModuleScopeProcedure ( identifierName , localScope , accessorType , isAssignmentTarget )
247
- ?? FindModuleScopeDeclaration ( identifierName , localScope )
248
- ?? FindProjectScopeDeclaration ( identifierName ) ;
260
+ callee = FindLocalScopeDeclaration ( identifierName , localScope , parentContext , isAssignmentTarget )
261
+ ?? FindModuleScopeProcedure ( identifierName , localScope , accessorType , isAssignmentTarget )
262
+ ?? FindModuleScopeDeclaration ( identifierName , localScope )
263
+ ?? FindProjectScopeDeclaration ( identifierName ) ;
249
264
}
250
265
251
266
if ( callee == null )
252
267
{
253
268
// calls inside With block can still refer to identifiers in _currentScope
254
269
localScope = _currentScope ;
255
270
identifierName = callSiteContext . GetText ( ) ;
256
- callee = FindLocalScopeDeclaration ( identifierName , localScope )
271
+ callee = FindLocalScopeDeclaration ( identifierName , localScope , parentContext , isAssignmentTarget )
257
272
?? FindModuleScopeProcedure ( identifierName , localScope , accessorType , isAssignmentTarget )
258
273
?? FindModuleScopeDeclaration ( identifierName , localScope )
259
274
?? FindProjectScopeDeclaration ( identifierName ) ;
@@ -692,14 +707,12 @@ private Declaration FindFunctionOrPropertyGetter(string identifierName, Declarat
692
707
693
708
var matches = _declarations [ identifierName ] ;
694
709
var parent = matches . SingleOrDefault ( item =>
695
- item . Scope == localScope . Scope
696
- && ( item . DeclarationType == DeclarationType . Function
697
- || item . DeclarationType == DeclarationType . PropertyGet ) ) ;
710
+ item . Scope == localScope . Scope ) ;
698
711
699
712
return parent ;
700
713
}
701
714
702
- private Declaration FindLocalScopeDeclaration ( string identifierName , Declaration localScope = null )
715
+ private Declaration FindLocalScopeDeclaration ( string identifierName , Declaration localScope = null , RuleContext parentContext = null , bool isAssignmentTarget = false )
703
716
{
704
717
if ( localScope == null )
705
718
{
@@ -712,21 +725,30 @@ private Declaration FindLocalScopeDeclaration(string identifierName, Declaration
712
725
return null ;
713
726
}
714
727
715
- if ( localScope . IdentifierName == identifierName
716
- && ( localScope . DeclarationType == DeclarationType . Function
717
- || localScope . DeclarationType == DeclarationType . PropertyGet ) )
718
- {
719
- return FindFunctionOrPropertyGetter ( identifierName , localScope ) ;
720
- }
721
-
722
728
var matches = _declarations [ identifierName ] ;
723
729
724
730
try
725
731
{
726
- return matches . SingleOrDefault ( item =>
732
+ var results = matches . Where ( item =>
727
733
item . ParentScope == localScope . Scope
728
734
&& localScope . Context . GetSelection ( ) . Contains ( item . Selection )
729
- && ! _moduleTypes . Contains ( item . DeclarationType ) ) ;
735
+ && ! _moduleTypes . Contains ( item . DeclarationType ) )
736
+ . ToList ( ) ;
737
+
738
+ if ( results . Count > 1 && isAssignmentTarget
739
+ && _returningMemberTypes . Contains ( localScope . DeclarationType )
740
+ && localScope . IdentifierName == identifierName
741
+ && parentContext is VBAParser . ICS_S_VariableOrProcedureCallContext )
742
+ {
743
+ // if we have multiple matches and we're in a returning member,
744
+ // in an in-statement variable or procedure call context that's
745
+ // the target of an assignment, then we have to assume we're looking
746
+ // at the assignment of the member's return value:
747
+ return FindFunctionOrPropertyGetter ( identifierName , localScope ) ;
748
+ }
749
+
750
+ // if we're not returning a function/getter value, then there can be only one:
751
+ return results . SingleOrDefault ( ) ;
730
752
}
731
753
catch ( InvalidOperationException )
732
754
{
0 commit comments