return new CharConstant ((char)v);
else if (t == TypeManager.bool_type)
return new BoolConstant ((bool) v);
+ else if (t == TypeManager.decimal_type)
+ return new DecimalConstant ((decimal)v);
else if (TypeManager.IsEnumType (t)){
- Constant e = Constantify (v, TypeManager.TypeToCoreType (v.GetType ()));
+ Constant e = Constantify (v, TypeManager.EnumToUnderlying (v.GetType ()));
return new EnumConstant (e, t);
} else
int count = mi.Length;
- if (count > 1)
- return new MethodGroupExpr (mi, loc);
-
if (mi [0] is MethodBase)
return new MethodGroupExpr (mi, loc);
+ if (mi [0] is PropertyInfo)
+ return new PropertyGroupExpr (mi, loc);
+
+ if (count > 1)
+ return null;
+
return ExprClassFromMemberInfo (ec, mi [0], loc);
}
if (real_target_type == TypeManager.float_type)
return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
OpCodes.Conv_R4);
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to ushort, int, uint, long, ulong, float, double
- //
- if ((real_target_type == TypeManager.ushort_type) ||
- (real_target_type == TypeManager.int32_type) ||
- (real_target_type == TypeManager.uint32_type))
- return new EmptyCast (expr, target_type);
- if (real_target_type == TypeManager.uint64_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
- if (real_target_type == TypeManager.int64_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
- if (real_target_type == TypeManager.float_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
- if (real_target_type == TypeManager.double_type)
- return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
} else if (expr_type == TypeManager.string_type){
if (real_target_type == TypeManager.bool_type)
return RTConversionExpression(ec, "System.Convert", ".ToSingle", expr, loc);
if (real_target_type == TypeManager.double_type)
return RTConversionExpression(ec, "System.Convert", ".ToDouble", expr, loc);
- if (real_target_type == TypeManager.char_type)
- return RTConversionExpression(ec, "System.Convert", ".ToChar", expr, loc);
}
return null;
(target_type == TypeManager.decimal_type))
return true;
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to ushort, int, uint, long, ulong, float, double
- //
- if ((target_type == TypeManager.ushort_type) ||
- (target_type == TypeManager.int32_type) ||
- (target_type == TypeManager.uint32_type) ||
- (target_type == TypeManager.uint64_type) ||
- (target_type == TypeManager.int64_type) ||
- (target_type == TypeManager.float_type) ||
- (target_type == TypeManager.double_type) ||
- (target_type == TypeManager.string_type) ||
- (target_type == TypeManager.decimal_type))
- return true;
-
} else if (expr_type == TypeManager.decimal_type) {
if (target_type == TypeManager.float_type ||
target_type == TypeManager.double_type)
if (ImplicitReferenceConversionExists (expr, expr_type, target_type))
return true;
+/*
if (expr is IntConstant){
int value = ((IntConstant) expr).Value;
if (v > 0)
return true;
}
+*/
if (target_type.IsSubclassOf (TypeManager.enum_type) && expr is IntLiteral){
IntLiteral i = (IntLiteral) expr;
(expr_type == TypeManager.decimal_type))
return true;
- } else if (target_type == TypeManager.char_type){
- //
- // To char from ushort, int, uint, long, ulong, float, double, decimal,string
- //
- if ((expr_type == TypeManager.ushort_type) ||
- (expr_type == TypeManager.int32_type) ||
- (expr_type == TypeManager.uint32_type) ||
- (expr_type == TypeManager.uint64_type) ||
- (expr_type == TypeManager.int64_type) ||
- (expr_type == TypeManager.float_type) ||
- (expr_type == TypeManager.double_type) ||
- (expr_type == TypeManager.decimal_type) ||
- (expr_type == TypeManager.string_type))
-
- return true;
-
} else if (target_type == TypeManager.decimal_type){
if (expr_type == TypeManager.float_type ||
expr_type == TypeManager.double_type)
Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_I8);
}
-
- } else if (target_type == TypeManager.char_type){
- //
- // To char from ushort, int, uint, long, ulong, float, double
- //
- if (expr_type == TypeManager.ushort_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_CH);
- if (expr_type == TypeManager.int32_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_CH);
- if (expr_type == TypeManager.uint32_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_CH);
- if (expr_type == TypeManager.uint64_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_CH);
- if (expr_type == TypeManager.int64_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_CH);
-
- if (expr_type == TypeManager.float_type) {
- Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_CH);
- }
- if (expr_type == TypeManager.double_type) {
- Expression rounded_expr = RTConversionExpression(ec, "System.Math", ".Round", expr, loc);
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_CH);
- }
} else if (target_type == TypeManager.float_type){
//
}
break;
case TypeCode.Byte:
- // Ok, this *is* broken
- e = RTConversionExpression(ec, "ByteType.FromObject", expr, loc);
- break;
+
+ switch (src_type) {
+ case TypeCode.String:
+ e = RTConversionExpression(ec, "BooleanType.FromString", expr, loc);
+ break;
+ case TypeCode.Object:
+ e = RTConversionExpression(ec, "ByteType.FromObject", expr, loc);
+ break;
+ }
+ break;
case TypeCode.Boolean:
switch (src_type) {
case TypeCode.String:
if (e != null)
return e;
+ if (expr is StringConstant && target_type == TypeManager.char_type)
+ return new CharConstant (((StringConstant) expr).Value [0]);
+
+ if (expr is CharConstant && target_type == TypeManager.string_type)
+ return new StringConstant (((CharConstant) expr).Value.ToString ());
+
e = ImplicitReferenceConversion (expr, target_type);
if (e != null)
return e;
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_CH);
} else if (expr_type == TypeManager.byte_type){
//
// From byte to sbyte and char
//
if (real_target_type == TypeManager.sbyte_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_I1);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_CH);
} else if (expr_type == TypeManager.short_type){
//
// From short to sbyte, byte, ushort, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_CH);
} else if (expr_type == TypeManager.ushort_type){
//
// From ushort to sbyte, byte, short, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_U1);
if (real_target_type == TypeManager.short_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_I2);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_CH);
} else if (expr_type == TypeManager.int32_type){
//
// From int to sbyte, byte, short, ushort, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_CH);
} else if (expr_type == TypeManager.uint32_type){
//
// From uint to sbyte, byte, short, ushort, int, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_U2);
if (real_target_type == TypeManager.int32_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_I4);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_CH);
} else if (expr_type == TypeManager.int64_type){
//
// From long to sbyte, byte, short, ushort, int, uint, ulong, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U4);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_CH);
} else if (expr_type == TypeManager.uint64_type){
//
// From ulong to sbyte, byte, short, ushort, int, uint, long, char
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_U4);
if (real_target_type == TypeManager.int64_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_CH);
- } else if (expr_type == TypeManager.char_type){
- //
- // From char to sbyte, byte, short
- //
- if (real_target_type == TypeManager.sbyte_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I1);
- if (real_target_type == TypeManager.byte_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_U1);
- if (real_target_type == TypeManager.short_type)
- return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I2);
} else if (expr_type == TypeManager.float_type){
//
// From float to sbyte, byte, short,
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_I8);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R4_CH);
} else if (expr_type == TypeManager.double_type){
//
// From double to byte, byte, short,
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_I8);
if (real_target_type == TypeManager.uint64_type)
return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_U8);
- if (real_target_type == TypeManager.char_type)
- return new ConvCast (ec, rounded_expr, target_type, ConvCast.Mode.R8_CH);
if (real_target_type == TypeManager.float_type)
return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_R4);
}
static void Error_ConstantValueCannotBeConverted (Location l, string val, Type t)
{
- Report.Error (31, l, "Constant value '" + val + "' cannot be converted to " +
+ Report.Error (30439, l, "Constant value '" + val + "' not representable in type " +
TypeManager.MonoBASIC_Name (t));
}
if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
if (target_type == TypeManager.int32_type){
if (v <= Int32.MaxValue)
return (int) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v >= 0 && v <= UInt32.MaxValue)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v <= UInt32.MaxValue)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
return (int) v;
else if (target_type == TypeManager.uint32_type)
return (uint) v;
- else if (target_type == TypeManager.char_type)
- return (char) v;
else if (target_type == TypeManager.sbyte_type){
if (v <= SByte.MaxValue)
return (sbyte) v;
else if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= 0)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= 0)
return (byte) v;
} else if (target_type == TypeManager.uint32_type){
if (v >= 0)
return (uint) v;
- } else if (target_type == TypeManager.char_type){
- if (v >= 0)
- return (char) v;
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
return (int) v;
else if (target_type == TypeManager.uint32_type)
return (uint) v;
- else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
- } else if (target_type == TypeManager.byte_type){
+ else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return (byte) v;
} else if (target_type == TypeManager.sbyte_type){
} else if (target_type == TypeManager.byte_type){
if (v >= Byte.MinValue && v <= Byte.MaxValue)
return new ByteConstant ((byte) System.Math.Round (v));
- } else if (target_type == TypeManager.char_type){
- if (v >= Char.MinValue && v <= Char.MaxValue)
- return (char) v;
} else if (target_type == TypeManager.short_type){
if (v >= Int16.MinValue && v <= Int16.MaxValue)
return new ShortConstant ((short) System.Math.Round (v));
/// </remarks>
public class SimpleName : Expression, ITypeExpression {
public readonly string Name;
+ bool is_invocation = false;
+ bool is_addressof = false;
+
+ public bool IsInvocation {
+ set {
+ is_invocation = value;
+ }
+ }
+
+ public bool IsAddressOf {
+ set {
+ is_addressof = value;
+ }
+ }
public SimpleName (string name, Location l)
{
if (ec.InvokingOwnOverload == false && current_block != null && current_block.IsVariableDefined (Name)){
LocalVariableReference var;
- var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+ var = new LocalVariableReference (current_block, Name, loc);
if (right_side != null)
return var.ResolveLValue (ec, right_side);
// #52067 - Start - Trying to solve
if (e == null) {
-
ArrayList lookups = new ArrayList();
ArrayList typelookups = new ArrayList();
// #52067 - End
- if (e == null)
- return DoResolveType (ec);
-
+ if (e == null) {
+
+ /* preparing to support automatic definition of variables on first usage with Option Explicit Off
+
+ Isn't good enough to enable just now (tries to define some internal links and breaks on emit)
+
+ if (Name.IndexOf ('.') == -1 && current_block != null && !Mono.MonoBASIC.Parser.OptionExplicit) {
+
+ // while looking for a real solution
+ if (Name != "anything")
+ return DoResolveType (ec);
+
+ Console.WriteLine("Implicitly adding a variable named '{0}'", Name);
+
+ // TODO: look at type-suffixes to correct name and type
+ Expression type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", loc);
+
+ current_block.AddVariable(ec, type, Name, loc);
+
+ LocalVariableReference var = new LocalVariableReference (current_block, Name, loc);
+ if (right_side != null)
+ return var.ResolveLValue (ec, right_side);
+ else
+ return var.Resolve (ec);
+ } else
+ */
+ return DoResolveType (ec);
+ }
+
if (e is TypeExpr)
return e;
if (e is IMemberExpr) {
+ if ((e is MethodGroupExpr) && !is_invocation && !is_addressof) {
+ Expression inv = new Invocation (this, new ArrayList (), loc);
+ return inv.Resolve (ec);
+ }
e = MemberAccess.ResolveMemberAccess (ec, e, null, loc, this);
if (e == null)
return null;
+ if (e is PropertyGroupExpr && is_invocation) // We dont know the arguments yet
+ return e;
+
IMemberExpr me = e as IMemberExpr;
if (me == null)
return e;
return null;
}
*/
+ bool isPropertyGroup = (e is PropertyGroupExpr);
if (right_side != null)
e = e.DoResolveLValue (ec, right_side);
else
e = e.DoResolve (ec);
+ if (e == null && isPropertyGroup && !is_invocation)
+ Error (30057, "Property '" + Name + "' cannot be invoked with given arguments");
+
return e;
}
- if (ec.IsStatic || ec.IsFieldInitializer){
+ if (ec.IsStatic || ec.IsFieldInitializer) {
if (allow_static)
return e;
return MemberStaticCheck (ec, e);
- } else
- return e;
+ }
+
+ return e;
}
public override void Emit (EmitContext ec)
return Name;
}
}
+
+ public class DecoratedIdentifier : Expression {
+ Expression id;
+ Type decoration;
+
+ public DecoratedIdentifier (Expression id, Type decoration)
+ {
+ this.id = id;
+ this.decoration = decoration;
+ }
+
+ override public Expression DoResolve (EmitContext ec)
+ {
+ if (id == null || decoration == null)
+ return null;
+
+ Expression ret = id.DoResolve (ec);
+ if (ret.Type != TypeManager.TypeToCoreType (decoration)) {
+ Report.Error (30277, id.Location, "Type character '" + decoration + "' does not match declared type '" + ret.Type + "'.");
+ return null;
+ }
+
+ return ret;
+ }
+
+ override public void Emit (EmitContext ec)
+ {
+ throw new InternalErrorException ("Should never be called");
+ }
+ }
/// <summary>
/// Fully resolved expression that evaluates to a type
}
}
+ /// <summary>
+ /// Property Group Expression.
+ ///
+ /// </summary>
+ public class PropertyGroupExpr : ExpressionStatement, IMemberExpr {
+ public PropertyInfo [] Properties;
+ Expression instance_expression = null;
+ bool is_explicit_impl = false;
+ MethodBase method = null;
+ bool indexer_access_req = false;
+ ArrayList arguments = null;
+
+ public PropertyGroupExpr (MemberInfo [] mi, Location l)
+ {
+ Properties = new PropertyInfo [mi.Length];
+ mi.CopyTo (Properties, 0);
+ eclass = ExprClass.PropertyAccess;
+ type = TypeManager.object_type;
+ loc = l;
+ }
+
+ public PropertyGroupExpr (MemberInfo [] mi, ArrayList args, Expression expr, Location l)
+ : this (mi, l)
+ {
+ arguments = args;
+ instance_expression = expr;
+ }
+
+ public PropertyGroupExpr (ArrayList list, Location l)
+ {
+ Properties = new PropertyInfo [list.Count];
+
+ try {
+ list.CopyTo (Properties, 0);
+ } catch {
+ foreach (MemberInfo m in list){
+ if (!(m is PropertyInfo)){
+ Console.WriteLine ("Name " + m.Name);
+ Console.WriteLine ("Found a: " + m.GetType ().FullName);
+ }
+ }
+ throw;
+ }
+ loc = l;
+ eclass = ExprClass.PropertyAccess;
+ type = TypeManager.object_type;
+ }
+
+ public ArrayList Arguments {
+ get {
+ return arguments;
+ }
+ set {
+ arguments = value;
+ }
+ }
+
+ public Type DeclaringType {
+ get {
+ return Properties [0].DeclaringType;
+ }
+ }
+
+ public bool IndexerAccessRequired {
+ get {
+ return indexer_access_req;
+ }
+ }
+
+ //
+ // 'A method group may have associated an instance expression'
+ //
+ public Expression InstanceExpression {
+ get {
+ return instance_expression;
+ }
+
+ set {
+ instance_expression = value;
+ }
+ }
+
+ public bool IsExplicitImpl {
+ get {
+ return is_explicit_impl;
+ }
+
+ set {
+ is_explicit_impl = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return Properties [0].Name;
+ }
+ }
+
+ public bool IsInstance {
+ get {
+ foreach (PropertyInfo pi in Properties) {
+ MethodInfo mi = pi.GetGetMethod ();
+ if (mi != null && !mi.IsStatic)
+ return true;
+ mi = pi.GetSetMethod ();
+ if (mi != null && !mi.IsStatic)
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public bool IsStatic {
+ get {
+ return (!IsInstance);
+ }
+ }
+
+ public ArrayList GetAccessors () {
+ ArrayList GetAccessors = new ArrayList ();
+ foreach (PropertyInfo pi in Properties) {
+ if (pi.GetGetMethod () != null)
+ GetAccessors.Add (pi.GetGetMethod ());
+/*
+ else if (pi.GetGetMethod (true) != null)
+ GetAccessors.Add (pi.GetGetMethod (true));
+*/
+
+ }
+ return GetAccessors;
+ }
+
+ public ArrayList SetAccessors () {
+ ArrayList SetAccessors = new ArrayList ();
+ foreach (PropertyInfo pi in Properties) {
+ if (pi.GetSetMethod () != null)
+ SetAccessors.Add (pi.GetSetMethod ());
+/*
+ else if (pi.GetSetMethod (true) != null)
+ SetAccessors.Add (pi.GetSetMethod (true));
+*/
+ }
+ return SetAccessors;
+ }
+
+ override public Expression DoResolve (EmitContext ec)
+ {
+ if (instance_expression != null) {
+ instance_expression = instance_expression.DoResolve (ec);
+ if (instance_expression == null)
+ return null;
+ }
+
+ ArrayList members = GetAccessors ();
+ if (members == null || members.Count == 0) {
+ Report.Error (30524, loc, "Property '" + Name + "' lacks a 'get' accesor");
+ return null;
+ }
+
+ MethodGroupExpr m_expr = new MethodGroupExpr (members, loc);
+ method = Invocation.OverloadResolve (ec, m_expr, ref arguments, loc);
+ if ((method as MethodInfo) != null) {
+ MethodInfo mi = method as MethodInfo;
+ type = TypeManager.TypeToCoreType (mi.ReturnType);
+ indexer_access_req = false;
+ eclass = ExprClass.Value;
+ return this;
+ } else {
+ // find a get method that doesnt take any arguments. Check the return type of
+ // that method to find out if indexer access is required. Leave the rest to
+ // 'Invocation's Resolve'
+ method = Invocation.OverloadResolve (ec, m_expr, null, loc);
+ if (method != null) {
+ MethodInfo mi = method as MethodInfo;
+ Type ret_type = mi.ReturnType;
+ if (ret_type.IsArray)
+ indexer_access_req = true;
+ else {
+ Indexers list = Indexers.GetIndexersForType (ec.ContainerType, ret_type, loc);
+ if (list != null && list.getters.Count > 0)
+ indexer_access_req = true;
+ else
+ return null;
+ }
+ Arguments = null;
+ type = mi.ReturnType;
+ return this;
+ }
+ }
+
+ return null;
+ }
+
+ override public Expression DoResolveLValue (EmitContext ec, Expression right_side) {
+ if (instance_expression != null) {
+ instance_expression = instance_expression.DoResolve (ec);
+ if (instance_expression == null)
+ return null;
+ }
+
+ ArrayList members = SetAccessors ();
+ if (members == null || members.Count == 0) {
+ Report.Error (30524, loc, "Property '" + Name + "' lacks a 'set' accesor");
+ return null;
+ }
+
+ MethodGroupExpr m_expr = new MethodGroupExpr (members, loc);
+ if (arguments == null)
+ arguments = new ArrayList ();
+ arguments.Add (new Argument (right_side, Argument.AType.Expression));
+ method = Invocation.OverloadResolve (ec, m_expr, ref arguments, loc);
+ if (method != null) {
+ //MethodInfo mi = method as MethodInfo;
+ type = TypeManager.void_type; //TypeManager.TypeToCoreType (mi.ReturnType);
+ eclass = ExprClass.Value;
+ indexer_access_req = false;
+ return this;
+ } else {
+ // Look for properties that do not take any arguments.
+ // Check if the return type has any indexers
+ arguments = null;
+ DoResolve (ec);
+ if (method != null) {
+ MethodInfo mi = method as MethodInfo;
+ Type ret_type = mi.ReturnType;
+ if (ret_type.IsArray)
+ indexer_access_req = true;
+ else {
+
+ Indexers list = Indexers.GetIndexersForType (ec.ContainerType,
+ ret_type, loc);
+ if (list != null && list.setters.Count > 0)
+ indexer_access_req = true;
+ else
+ return null;
+ }
+ type = mi.ReturnType;
+ return this;
+ }
+ }
+
+ return null;
+ }
+
+ override public void Emit (EmitContext ec)
+ {
+ if (Arguments == null)
+ Arguments = new ArrayList ();
+ Invocation.EmitCall (ec, false, IsStatic, instance_expression, method, null, Arguments, loc);
+ }
+
+ override public void EmitStatement (EmitContext ec)
+ {
+ Emit (ec);
+ }
+
+ }
+
/// <summary>
/// Fully resolved expression that evaluates to a Field
/// </summary>