//
// This is so we can catch correctly attempts to invoke instance methods
// from a static body (scan for error 120 in ResolveSimpleName).
- //
- protected static Expression MemberLookup (RootContext rc, Type t, string name, bool same_type)
- {
- MemberTypes mt =
- MemberTypes.Constructor |
- MemberTypes.Event |
- MemberTypes.Field |
- MemberTypes.Method |
- MemberTypes.NestedType |
- MemberTypes.Property;
-
- BindingFlags bf =
- BindingFlags.Public |
- BindingFlags.Static |
- BindingFlags.Instance;
-
+ //
+ public static Expression MemberLookup (RootContext rc, Type t, string name,
+ bool same_type, MemberTypes mt, BindingFlags bf)
+ {
if (same_type)
bf |= BindingFlags.NonPublic;
return new MethodGroupExpr (mi);
}
+
+ public const MemberTypes AllMemberTypes =
+ MemberTypes.Constructor |
+ MemberTypes.Event |
+ MemberTypes.Field |
+ MemberTypes.Method |
+ MemberTypes.NestedType |
+ MemberTypes.Property;
+
+ public const BindingFlags AllBindingsFlags =
+ BindingFlags.Public |
+ BindingFlags.Static |
+ BindingFlags.Instance;
+
+ public static Expression MemberLookup (RootContext rc, Type t, string name,
+ bool same_type)
+ {
+ return MemberLookup (rc, t, name, same_type, AllMemberTypes, AllBindingsFlags);
+ }
// <summary>
// Resolves the E in `E.I' side for a member_access
public class Binary : Expression {
public enum Operator {
Multiply, Divide, Modulo,
- Add, Substract,
+ Add, Subtract,
ShiftLeft, ShiftRight,
- LessThan, GreatherThan, LessOrEqual, GreatherOrEqual,
+ LessThan, GreaterThan, LessOrEqual, GreaterOrEqual,
Equal, NotEqual,
BitwiseAnd,
ExclusiveOr,
Operator oper;
Expression left, right;
+ MethodBase method;
+ ArrayList Arguments;
public Binary (Operator oper, Expression left, Expression right)
{
return "%";
case Operator.Add:
return "+";
- case Operator.Substract:
+ case Operator.Subtract:
return "-";
case Operator.ShiftLeft:
return "<<";
return ">>";
case Operator.LessThan:
return "<";
- case Operator.GreatherThan:
+ case Operator.GreaterThan:
return ">";
case Operator.LessOrEqual:
return "<=";
- case Operator.GreatherOrEqual:
+ case Operator.GreaterOrEqual:
return ">=";
case Operator.Equal:
return "==";
//
// Step 1: Perform Operator Overload location
//
-
+ Expression left_expr, right_expr;
+ string op = "Operator" + oper;
+
+ left_expr = MemberLookup (tc.RootContext, l, op, false);
+
+ if (!(left_expr is MethodGroupExpr)){
+ // FIXME: Find proper error
+ tc.RootContext.Report.Error (118, "Did find something that is not a method");
+ return null;
+ }
+
+ right_expr = MemberLookup (tc.RootContext, r, op, false);
+
+ if (!(right_expr is MethodGroupExpr)){
+ // FIXME: Find proper error
+ tc.RootContext.Report.Error (118, "Did find something that is not a method");
+ return null;
+ }
+
+ if (left_expr != null || right_expr != null) {
+ //
+ // Now we need to form the union of these two sets and
+ // then call OverloadResolve
+ // on that.
+ //
+ MethodGroupExpr left_set = null, right_set = null;
+ int length1 = 0, length2 = 0;
+
+ if (left_expr != null) {
+ left_set = (MethodGroupExpr) left_expr;
+ length1 = left_set.Methods.Length;
+ }
+
+ if (right_expr != null) {
+ right_set = (MethodGroupExpr) right_expr;
+ length2 = right_set.Methods.Length;
+ }
+
+ MemberInfo [] mi = new MemberInfo [length1 + length2];
+ if (left_set != null)
+ left_set.Methods.CopyTo (mi, 0);
+ if (right_set != null)
+ right_set.Methods.CopyTo (mi, length1);
+
+ MethodGroupExpr union = new MethodGroupExpr (mi);
+
+ Arguments = new ArrayList ();
+ Arguments.Add (new Argument (left, Argument.AType.Expression));
+ Arguments.Add (new Argument (right, Argument.AType.Expression));
+
+ method = Invocation.OverloadResolve (union, Arguments);
+ if (method != null)
+ return this;
+
+ }
+
//
// Step 2: Default operations on CLI native types.
//
-
+
// Only perform numeric promotions on:
// +, -, *, /, %, &, |, ^, ==, !=, <, >, <=, >=
//
oper == Operator.NotEqual ||
oper == Operator.LessOrEqual ||
oper == Operator.LessThan ||
- oper == Operator.GreatherOrEqual ||
- oper == Operator.GreatherThan){
+ oper == Operator.GreaterOrEqual ||
+ oper == Operator.GreaterThan){
type = TypeManager.bool_type;
}
if (oper == Operator.Equal ||
oper == Operator.NotEqual ||
oper == Operator.LessThan ||
- oper == Operator.GreatherThan ||
+ oper == Operator.GreaterThan ||
oper == Operator.LessOrEqual ||
- oper == Operator.GreatherOrEqual){
+ oper == Operator.GreaterOrEqual){
return true;
} else
return false;
opcode = OpCodes.Blt;
break;
- case Operator.GreatherThan:
+ case Operator.GreaterThan:
if (close_target)
opcode = OpCodes.Bgt_S;
else
opcode = OpCodes.Ble;
break;
- case Operator.GreatherOrEqual:
+ case Operator.GreaterOrEqual:
if (close_target)
opcode = OpCodes.Bge_S;
else
Type l = left.Type;
Type r = right.Type;
OpCode opcode;
+
+ if (method != null) {
+ if (method is MethodInfo) {
+ Invocation.EmitArguments (ec, Arguments);
+ ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
+ return;
+ }
+ }
left.Emit (ec);
right.Emit (ec);
opcode = OpCodes.Add;
break;
- case Operator.Substract:
+ case Operator.Subtract:
if (ec.CheckState){
if (l == TypeManager.int32_type || l == TypeManager.int64_type)
opcode = OpCodes.Sub_Ovf;
opcode = OpCodes.Clt;
break;
- case Operator.GreatherThan:
+ case Operator.GreaterThan:
opcode = OpCodes.Cgt;
break;
opcode = OpCodes.Ceq;
break;
- case Operator.GreatherOrEqual:
+ case Operator.GreaterOrEqual:
ec.ig.Emit (OpCodes.Clt);
ec.ig.Emit (OpCodes.Ldc_I4_1);
// Returns the Parameters (a ParameterData interface) for the
// Method `mb'
// </summary>
- static ParameterData GetParameterData (TypeContainer tc, MethodBase mb)
+ static ParameterData GetParameterData (MethodBase mb)
{
object pd = method_parameter_cache [mb];
// <summary>
// Find the Applicable Function Members (7.4.2.1)
+ //
+ // me: Method Group expression with the members to select.
+ // it might contain constructors or methods (or anything
+ // that maps to a method).
+ //
+ // Arguments: ArrayList containing resolved Argument objects.
+ //
+ // Returns: The MethodBase (either a ConstructorInfo or a MethodInfo)
+ // that is the best match of me on Arguments.
+ //
// </summary>
- public static MethodBase OverloadResolve (TypeContainer tc, MethodGroupExpr me,
- ArrayList Arguments)
+ public static MethodBase OverloadResolve (MethodGroupExpr me, ArrayList Arguments)
{
ArrayList afm = new ArrayList ();
int best_match = 10000;
MethodBase mb = me.Methods [i];
ParameterData pd;
- pd = GetParameterData (tc, mb);
+ pd = GetParameterData (mb);
+
+ // If this is the case, we have a method with no args - presumably
+ if (pd == null && argument_count == 0)
+ return me.Methods [0];
//
// Compute how good this is
}
}
- method = OverloadResolve (tc, (MethodGroupExpr) this.expr, Arguments);
+ method = OverloadResolve ((MethodGroupExpr) this.expr, Arguments);
if (method == null){
tc.RootContext.Report.Error (-6,
mg.InstanceExpression.Emit (ec);
}
-
- EmitArguments (ec, Arguments);
- if (method.IsVirtual){
+ if (Arguments != null)
+ EmitArguments (ec, Arguments);
+
+ if (method.IsStatic){
if (method is MethodInfo)
- ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+ ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
else
- ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+ ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
} else {
if (method is MethodInfo)
- ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
+ ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
else
- ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
- }
+ ec.ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
+ }
+
}
}
Expression ml;
- MemberTypes mt =
- MemberTypes.Constructor;
-
- BindingFlags bf =
- BindingFlags.Public |
- BindingFlags.Instance;
-
- MemberInfo [] mi = tc.RootContext.TypeManager.FindMembers (type, mt, bf, null, null);
-
- Console.WriteLine ("Found: " + mi.Length);
- for (int i = 0; i < mi.Length; i++)
- Console.WriteLine (" " + i + ": " + mi [i]);
-
- ml = MemberLookup (tc.RootContext, type, ".ctor", false);
+ ml = MemberLookup (tc.RootContext, type, ".ctor", false,
+ MemberTypes.Constructor, AllBindingsFlags);
if (! (ml is MethodGroupExpr)){
//
}
}
- method = Invocation.OverloadResolve (tc, (MethodGroupExpr) ml, Arguments);
+ method = Invocation.OverloadResolve ((MethodGroupExpr) ml, Arguments);
if (method == null){
tc.RootContext.Report.Error (-6,
}
}
-
- public class ElementAccess : Expression {
-
+
+ public class ElementAccess : Expression {
+
public readonly ArrayList Arguments;
public readonly Expression Expr;
-
+
public ElementAccess (Expression e, ArrayList e_list)
{
Expr = e;
// FIXME : Implement
return this;
}
-
+
public override void Emit (EmitContext ec)
{
// FIXME : Implement !
}
-
+
}
-
+
public class BaseAccess : Expression {
public enum BaseAccessType {