Skip to content

Commit 426dc00

Browse files
committed
Fix named argument resolution on default member accesses
1 parent c5ab99e commit 426dc00

File tree

4 files changed

+141
-88
lines changed

4 files changed

+141
-88
lines changed

Rubberduck.Parsing/Binding/Bindings/DictionaryAccessDefaultBinding.cs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public DictionaryAccessDefaultBinding(
4040
_argumentList = argumentList;
4141
}
4242

43-
private void ResolveArgumentList(Declaration calledProcedure)
43+
private static void ResolveArgumentList(Declaration calledProcedure, ArgumentList argumentList)
4444
{
45-
foreach (var argument in _argumentList.Arguments)
45+
foreach (var argument in argumentList.Arguments)
4646
{
4747
argument.Resolve(calledProcedure);
4848
}
@@ -55,49 +55,54 @@ public IBoundExpression Resolve()
5555
_lExpression = _lExpressionBinding.Resolve();
5656
}
5757

58-
if (_lExpression.Classification == ExpressionClassification.ResolutionFailed)
58+
return Resolve(_lExpression, _argumentList, _expression);
59+
}
60+
61+
private static IBoundExpression Resolve(IBoundExpression lExpression, ArgumentList argumentList, ParserRuleContext expression)
62+
{
63+
if (lExpression.Classification == ExpressionClassification.ResolutionFailed)
5964
{
60-
ResolveArgumentList(null);
61-
return CreateFailedExpression(_lExpression);
65+
ResolveArgumentList(null, argumentList);
66+
return CreateFailedExpression(lExpression, argumentList);
6267
}
6368

64-
var lDeclaration = _lExpression.ReferencedDeclaration;
69+
var lDeclaration = lExpression.ReferencedDeclaration;
6570

66-
if (_lExpression.Classification == ExpressionClassification.Unbound)
71+
if (lExpression.Classification == ExpressionClassification.Unbound)
6772
{
6873
/*
6974
<l-expression> is classified as an unbound member. In this case, the dictionary access expression
7075
is classified as an unbound member with a declared type of Variant, referencing <l-expression> with no member name.
7176
*/
72-
ResolveArgumentList(lDeclaration);
73-
return new DictionaryAccessExpression(null, ExpressionClassification.Unbound, _expression, _lExpression, _argumentList);
77+
ResolveArgumentList(lDeclaration, argumentList);
78+
return new DictionaryAccessExpression(null, ExpressionClassification.Unbound, expression, lExpression, argumentList);
7479
}
7580

7681
if (lDeclaration == null)
7782
{
78-
ResolveArgumentList(null);
79-
return CreateFailedExpression(_lExpression);
83+
ResolveArgumentList(null, argumentList);
84+
return CreateFailedExpression(lExpression, argumentList);
8085
}
8186

8287
var asTypeName = lDeclaration.AsTypeName;
8388
var asTypeDeclaration = lDeclaration.AsTypeDeclaration;
8489

85-
return ResolveViaDefaultMember(_lExpression, asTypeName, asTypeDeclaration);
90+
return ResolveViaDefaultMember(lExpression, asTypeName, asTypeDeclaration, argumentList, expression);
8691
}
8792

88-
private IBoundExpression CreateFailedExpression(IBoundExpression lExpression)
93+
private static IBoundExpression CreateFailedExpression(IBoundExpression lExpression, ArgumentList argumentList)
8994
{
9095
var failedExpr = new ResolutionFailedExpression();
9196
failedExpr.AddSuccessfullyResolvedExpression(lExpression);
92-
foreach (var arg in _argumentList.Arguments)
97+
foreach (var arg in argumentList.Arguments)
9398
{
9499
failedExpr.AddSuccessfullyResolvedExpression(arg.Expression);
95100
}
96101

97102
return failedExpr;
98-
}
103+
}
99104

100-
private IBoundExpression ResolveViaDefaultMember(IBoundExpression lExpression, string asTypeName, Declaration asTypeDeclaration, int recursionDepth = 0)
105+
private static IBoundExpression ResolveViaDefaultMember(IBoundExpression lExpression, string asTypeName, Declaration asTypeDeclaration, ArgumentList argumentList, ParserRuleContext expression, int recursionDepth = 0)
101106
{
102107
if (Tokens.Variant.Equals(asTypeName, StringComparison.InvariantCultureIgnoreCase)
103108
|| Tokens.Object.Equals(asTypeName, StringComparison.InvariantCultureIgnoreCase))
@@ -107,8 +112,8 @@ The declared type of <l-expression> is Object or Variant.
107112
In this case, the dictionary access expression is classified as an unbound member with
108113
a declared type of Variant, referencing <l-expression> with no member name.
109114
*/
110-
ResolveArgumentList(null);
111-
return new DictionaryAccessExpression(null, ExpressionClassification.Unbound, _expression, lExpression, _argumentList);
115+
ResolveArgumentList(null, argumentList);
116+
return new DictionaryAccessExpression(null, ExpressionClassification.Unbound, expression, lExpression, argumentList);
112117
}
113118

114119
/*
@@ -120,8 +125,8 @@ The declared type of <l-expression> is Object or Variant.
120125
|| !IsPropertyGetLetFunctionProcedure(defaultMember)
121126
|| !IsPublic(defaultMember))
122127
{
123-
ResolveArgumentList(null);
124-
return CreateFailedExpression(lExpression);
128+
ResolveArgumentList(null, argumentList);
129+
return CreateFailedExpression(lExpression, argumentList);
125130
}
126131

127132
var defaultMemberClassification = DefaultMemberClassification(defaultMember);
@@ -135,8 +140,8 @@ The declared type of <l-expression> is Object or Variant.
135140
dictionary access expression references this default member and takes on its classification and
136141
declared type.
137142
*/
138-
ResolveArgumentList(defaultMember);
139-
return new DictionaryAccessExpression(defaultMember, defaultMemberClassification, _expression, lExpression, _argumentList);
143+
ResolveArgumentList(defaultMember, argumentList);
144+
return new DictionaryAccessExpression(defaultMember, defaultMemberClassification, expression, lExpression, argumentList);
140145
}
141146

142147
if (parameters.Count(param => !param.IsOptional) == 0
@@ -148,11 +153,11 @@ declared type.
148153
same <argument-list>.
149154
*/
150155

151-
return ResolveRecursiveDefaultMember(defaultMember, defaultMemberClassification, recursionDepth);
156+
return ResolveRecursiveDefaultMember(defaultMember, defaultMemberClassification, argumentList, expression, recursionDepth);
152157
}
153158

154-
ResolveArgumentList(null);
155-
return CreateFailedExpression(lExpression);
159+
ResolveArgumentList(null, argumentList);
160+
return CreateFailedExpression(lExpression, argumentList);
156161
}
157162

158163
private static bool IsCompatibleWithOneStringArgument(List<ParameterDeclaration> parameters)
@@ -163,16 +168,18 @@ private static bool IsCompatibleWithOneStringArgument(List<ParameterDeclaration>
163168
|| Tokens.Variant.Equals(parameters[0].AsTypeName, StringComparison.InvariantCultureIgnoreCase));
164169
}
165170

166-
private IBoundExpression ResolveRecursiveDefaultMember(Declaration defaultMember, ExpressionClassification defaultMemberClassification, int recursionDepth)
171+
private static IBoundExpression ResolveRecursiveDefaultMember(Declaration defaultMember, ExpressionClassification defaultMemberClassification, ArgumentList argumentList, ParserRuleContext expression, int recursionDepth)
167172
{
168-
var defaultMemberAsLExpression = new SimpleNameExpression(defaultMember, defaultMemberClassification, _expression);
173+
var defaultMemberAsLExpression = new SimpleNameExpression(defaultMember, defaultMemberClassification, expression);
169174
var defaultMemberAsTypeName = defaultMember.AsTypeName;
170175
var defaultMemberAsTypeDeclaration = defaultMember.AsTypeDeclaration;
171176

172177
return ResolveViaDefaultMember(
173178
defaultMemberAsLExpression,
174179
defaultMemberAsTypeName,
175180
defaultMemberAsTypeDeclaration,
181+
argumentList,
182+
expression,
176183
recursionDepth + 1);
177184
}
178185

@@ -193,7 +200,7 @@ private static bool IsPublic(Declaration declaration)
193200
|| accessibility == Accessibility.Public;
194201
}
195202

196-
private ExpressionClassification DefaultMemberClassification(Declaration defaultMember)
203+
private static ExpressionClassification DefaultMemberClassification(Declaration defaultMember)
197204
{
198205
if (defaultMember.DeclarationType.HasFlag(DeclarationType.Property))
199206
{

0 commit comments

Comments
 (0)