private EXPR BindProperty(
DynamicMetaObjectBinder payload,
ArgumentObject argument,
LocalVariableSymbol local,
EXPR optionalIndexerArguments,
bool fEventsPermitted)
{
// If our argument is a static type, then we're calling a static property.
EXPR callingObject = argument.Info.IsStaticType ?
_exprFactory.CreateClass(_symbolTable.GetCTypeFromType(argument.Value as Type), null, null) :
CreateLocal(argument.Type, argument.Info.IsOut, local);
if (!argument.Info.UseCompileTimeType && argument.Value == null)
{
throw Error.NullReferenceOnMemberException();
}
// If our argument is a struct type, unbox it.
if (argument.Type.GetTypeInfo().IsValueType && callingObject.isCAST())
{
// If we have a struct type, unbox it.
callingObject.flags |= EXPRFLAG.EXF_UNBOXRUNTIME;
}
string name = GetName(payload);
BindingFlag bindFlags = GetBindingFlags(payload);
MemberLookup mem = new MemberLookup();
SymWithType swt = _symbolTable.LookupMember(name, callingObject, _bindingContext.ContextForMemberLookup(), 0, mem, false, false);
if (swt == null)
{
if (optionalIndexerArguments != null)
{
int numIndexArguments = ExpressionIterator.Count(optionalIndexerArguments);
// We could have an array access here. See if its just an array.
if ((argument.Type.IsArray && argument.Type.GetArrayRank() == numIndexArguments) ||
argument.Type == typeof(string))
{
return CreateArray(callingObject, optionalIndexerArguments);
}
}
mem.ReportErrors();
Debug.Assert(false, "Why didn't member lookup report an error?");
}
switch (swt.Sym.getKind())
{
case SYMKIND.SK_MethodSymbol:
throw Error.BindPropertyFailedMethodGroup(name);
case SYMKIND.SK_PropertySymbol:
if (swt.Sym is IndexerSymbol)
{
return CreateIndexer(swt, callingObject, optionalIndexerArguments, bindFlags);
}
else
{
BindingFlag flags = 0;
if (payload is CSharpGetMemberBinder || payload is CSharpGetIndexBinder)
{
flags = BindingFlag.BIND_RVALUEREQUIRED;
}
// Properties can be LValues.
callingObject.flags |= EXPRFLAG.EXF_LVALUE;
return CreateProperty(swt, callingObject, flags);
}
case SYMKIND.SK_FieldSymbol:
return CreateField(swt, callingObject);
case SYMKIND.SK_EventSymbol:
if (fEventsPermitted)
{
return CreateEvent(swt, callingObject);
}
else
{
throw Error.BindPropertyFailedEvent(name);
}
default:
Debug.Assert(false, "Unexpected type returned from lookup");
throw Error.InternalCompilerError();
}
}