private EXPR BindCall(
ICSharpInvokeOrInvokeMemberBinder payload,
EXPR callingObject,
ArgumentObject[] arguments,
Dictionary<int, LocalVariableSymbol> dictionary)
{
if (payload is InvokeBinder && !callingObject.type.isDelegateType())
{
throw Error.BindInvokeFailedNonDelegate();
}
EXPR pResult = null;
int arity = payload.TypeArguments != null ? payload.TypeArguments.Count : 0;
MemberLookup mem = new MemberLookup();
Debug.Assert(_bindingContext.ContextForMemberLookup() != null);
SymWithType swt = _symbolTable.LookupMember(
payload.Name,
callingObject,
_bindingContext.ContextForMemberLookup(),
arity,
mem,
(payload.Flags & CSharpCallFlags.EventHookup) != 0,
true);
if (swt == null)
{
mem.ReportErrors();
Debug.Assert(false, "Why didn't member lookup report an error?");
}
if (swt.Sym.getKind() != SYMKIND.SK_MethodSymbol)
{
Debug.Assert(false, "Unexpected type returned from lookup");
throw Error.InternalCompilerError();
}
// At this point, we're set up to do binding. We need to do the following:
//
// 1) Create the EXPRLOCALs for the arguments, linking them to the local
// variable symbols defined above.
// 2) Create the EXPRMEMGRP for the call and the EXPRLOCAL for the object
// of the call, and link the correct local variable symbol as above.
// 3) Do overload resolution to get back an EXPRCALL.
//
// Our caller takes care of the rest.
// First we need to check the sym that we got back. If we got back a static
// method, then we may be in the situation where the user called the method
// via a simple name call through the phantom overload. If thats the case,
// then we want to sub in a type instead of the object.
EXPRMEMGRP memGroup = CreateMemberGroupEXPR(payload.Name, payload.TypeArguments, callingObject, swt.Sym.getKind());
if ((payload.Flags & CSharpCallFlags.SimpleNameCall) != 0)
{
callingObject.flags |= EXPRFLAG.EXF_SIMPLENAME;
}
if ((payload.Flags & CSharpCallFlags.EventHookup) != 0)
{
mem = new MemberLookup();
SymWithType swtEvent = _symbolTable.LookupMember(
payload.Name.Split('_')[1],
callingObject,
_bindingContext.ContextForMemberLookup(),
arity,
mem,
(payload.Flags & CSharpCallFlags.EventHookup) != 0,
true);
if (swtEvent == null)
{
mem.ReportErrors();
Debug.Assert(false, "Why didn't member lookup report an error?");
}
CType eventCType = null;
if (swtEvent.Sym.getKind() == SYMKIND.SK_FieldSymbol)
{
eventCType = swtEvent.Field().GetType();
}
else if (swtEvent.Sym.getKind() == SYMKIND.SK_EventSymbol)
{
eventCType = swtEvent.Event().type;
}
Type eventType = SymbolLoader.GetTypeManager().SubstType(eventCType, swtEvent.Ats).AssociatedSystemType;
if (eventType != null)
{
// If we have an event hookup, first find the event itself.
BindImplicitConversion(new ArgumentObject[] { arguments[1] }, eventType, dictionary, false);
}
memGroup.flags &= ~EXPRFLAG.EXF_USERCALLABLE;
if (swtEvent.Sym.getKind() == SYMKIND.SK_EventSymbol && swtEvent.Event().IsWindowsRuntimeEvent)
{
return BindWinRTEventAccessor(
new EventWithType(swtEvent.Event(), swtEvent.Ats),
callingObject,
arguments,
dictionary,
payload.Name.StartsWith("add_", StringComparison.Ordinal)); //isAddAccessor?
}
}
// Check if we have a potential call to an indexed property accessor.
// If so, we'll flag overload resolution to let us call non-callables.
if ((payload.Name.StartsWith("set_", StringComparison.Ordinal) && swt.Sym.AsMethodSymbol().Params.Size > 1) ||
(payload.Name.StartsWith("get_", StringComparison.Ordinal) && swt.Sym.AsMethodSymbol().Params.Size > 0))
{
memGroup.flags &= ~EXPRFLAG.EXF_USERCALLABLE;
}
pResult = _binder.BindMethodGroupToArguments(// Tree
BindingFlag.BIND_RVALUEREQUIRED | BindingFlag.BIND_STMTEXPRONLY, memGroup, CreateArgumentListEXPR(arguments, dictionary, 1, arguments.Length));
// If overload resolution failed, throw an error.
if (pResult == null || !pResult.isOK())
{
throw Error.BindCallFailedOverloadResolution();
}
CheckForConditionalMethodError(pResult);
return ReorderArgumentsForNamedAndOptional(callingObject, pResult);
}