@@ -228,6 +228,41 @@ type.SpecialType is SpecialType.System_IntPtr ||
228228 return Literal . CreateGenerated ( cx , parent , childIndex , type , defaultValue , location ) ;
229229 }
230230
231+ /// <summary>
232+ /// Given an expression syntax node, attempt to resolve the target method symbol for it.
233+ /// The operation takes extension methods into account.
234+ /// </summary>
235+ /// <param name="node">The expression syntax node.</param>
236+ /// <returns>Returns the target method symbol, or null if it cannot be resolved.</returns>
237+ protected IMethodSymbol ? GetTargetSymbol ( ExpressionSyntax node )
238+ {
239+ var si = Context . GetSymbolInfo ( node ) ;
240+ if ( si . Symbol is ISymbol symbol )
241+ {
242+ var method = symbol as IMethodSymbol ;
243+ // Case for compiler-generated extension methods.
244+ return method ? . TryGetExtensionMethod ( ) ?? method ;
245+ }
246+
247+ if ( si . CandidateReason == CandidateReason . OverloadResolutionFailure && node is InvocationExpressionSyntax syntax )
248+ {
249+ // This seems to be a bug in Roslyn
250+ // For some reason, typeof(X).InvokeMember(...) fails to resolve the correct
251+ // InvokeMember() method, even though the number of parameters clearly identifies the correct method
252+
253+ var candidates = si . CandidateSymbols
254+ . OfType < IMethodSymbol > ( )
255+ . Where ( method => method . Parameters . Length >= syntax . ArgumentList . Arguments . Count )
256+ . Where ( method => method . Parameters . Count ( p => ! p . HasExplicitDefaultValue ) <= syntax . ArgumentList . Arguments . Count ) ;
257+
258+ return Context . ExtractionContext . IsStandalone ?
259+ candidates . FirstOrDefault ( ) :
260+ candidates . SingleOrDefault ( ) ;
261+ }
262+
263+ return si . Symbol as IMethodSymbol ;
264+ }
265+
231266 /// <summary>
232267 /// Adapt the operator kind depending on whether it's a dynamic call or a user-operator call.
233268 /// </summary>
@@ -244,10 +279,10 @@ public static ExprKind UnaryOperatorKind(Context cx, ExprKind originalKind, Expr
244279 /// name if available.
245280 /// </summary>
246281 /// <param name="node">The expression.</param>
247- public void OperatorCall ( TextWriter trapFile , ExpressionSyntax node )
282+ public void AddOperatorCall ( TextWriter trapFile , ExpressionSyntax node )
248283 {
249- var @operator = Context . GetSymbolInfo ( node ) ;
250- if ( @operator . Symbol is IMethodSymbol method )
284+ var @operator = GetTargetSymbol ( node ) ;
285+ if ( @operator is IMethodSymbol method )
251286 {
252287 var callType = GetCallType ( Context , node ) ;
253288 if ( callType == CallType . Dynamic )
0 commit comments