//
// 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;
if (mi.Length == 1 && !(mi [0] is MethodBase))
return Expression.ExprClassFromMemberInfo (mi [0]);
-
+
for (int i = 0; i < mi.Length; i++)
if (!(mi [i] is MethodBase)){
rc.Report.Error (-5, "Do not know how to reproduce this case: " +
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
Expression left, right;
MethodBase method;
ArrayList Arguments;
+
public Binary (Operator oper, Expression left, Expression right)
{
//
// Step 1: Perform Operator Overload location
//
- Expression i, j;
+ Expression left_expr, right_expr;
string op = "Operator" + oper;
- i = MemberLookup (tc.RootContext, l, op, false);
+ left_expr = MemberLookup (tc.RootContext, l, op, false);
- if (!(i is MethodGroupExpr)){
+ if (!(left_expr is MethodGroupExpr)){
// FIXME: Find proper error
tc.RootContext.Report.Error (118, "Did find something that is not a method");
return null;
}
-
- j = MemberLookup (tc.RootContext, r, op, false);
- if (!(j is MethodGroupExpr)){
+ 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;
}
- // Now we need to form the union of these two sets and then call OverloadResolve
- // on that.
- MethodGroupExpr left_set = (MethodGroupExpr) i;
- MethodGroupExpr right_set = (MethodGroupExpr) j;
-
- int length1, length2;
- length1 = left_set.Methods.Length;
- length2 = right_set.Methods.Length;
+ 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;
+ }
- MemberInfo [] mi = new MemberInfo [length1 + length2];
- left_set.Methods.CopyTo (mi, 0);
- right_set.Methods.CopyTo (mi, length1);
-
- MethodGroupExpr union = new MethodGroupExpr (mi);
+ if (right_expr != null) {
+ right_set = (MethodGroupExpr) right_expr;
+ length2 = right_set.Methods.Length;
+ }
- Arguments = new ArrayList ();
- Arguments.Add (new Argument (left, Argument.AType.Expression));
- Arguments.Add (new Argument (right, Argument.AType.Expression));
-
- method = Invocation.OverloadResolve (tc, union, Arguments);
- if (method != null)
- return this;
+ 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:
// +, -, *, /, %, &, |, ^, ==, !=, <, >, <=, >=
//
OpCode opcode;
if (method != null) {
- if (method is MethodInfo) {
- Invocation.EmitArguments (ec, Arguments);
- ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
- return;
- }
+
+ bool is_static = method.IsStatic;
+
+ // FIXME : I am just not able to get this right !!
+ // There's something wrong with this part which causes
+ // an InvalidProgramException if this code is emitted
+
+ //if (Arguments != null)
+ // Invocation.EmitArguments (ec, Arguments);
+
+ //if (is_static){
+ // if (method is MethodInfo)
+ // ig.Emit (OpCodes.Call, (MethodInfo) method);
+ // else
+ // ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+ //} else {
+ // if (method is MethodInfo)
+ // ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+ // else
+ // ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
+ //}
+
+ //return;
}
left.Emit (ec);
if (e != null){
if (e is TypeExpr)
return e;
+ else if (e is FieldExpr){
+ FieldExpr fe = (FieldExpr) e;
+
+ if (!fe.FieldInfo.IsStatic)
+ fe.Instance = new This ();
+ }
+
if ((tc.ModFlags & Modifiers.STATIC) != 0)
return MemberStaticCheck (r, e);
else
throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
}
- if (t == a.Expr.Type)
+ if (t == a.Expr.Type)
return 0;
-
+
// FIXME: Implement implicit conversions here.
// FIXME: Implement better conversion here.
// 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 (is_static){
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){
+ if (method == null) {
tc.RootContext.Report.Error (-6,
"New invocation: Can not find a constructor for this argument list");
return null;
}
}
+ //
+ // Represents the `this' construct
+ //
public class This : Expression {
public override Expression Resolve (TypeContainer tc)
{
- // FIXME: Implement;
+ eclass = ExprClass.Variable;
+ type = tc.TypeBuilder;
+
return this;
}
public override void Emit (EmitContext ec)
{
+ ec.ig.Emit (OpCodes.Ldarg_0);
}
}
public override Expression Resolve (TypeContainer tc)
{
- // FIXME: Implement;
+ type = tc.LookupType (QueriedType, false);
+
+ if (type == null)
+ return null;
+
+ eclass = ExprClass.Type;
return this;
}
public override void Emit (EmitContext ec)
{
+ // FIXME: Implement.
}
}
// FIXME: This is a horrible way of detecting if it is
// an instance expression. Figure out how to fix this.
//
- Console.WriteLine ("FIXME: Horrible way of figuring if something is an isntance");
- if (expr is LocalVariableReference)
+ if (expr is LocalVariableReference ||
+ expr is ParameterReference ||
+ expr is FieldExpr)
mg.InstanceExpression = expr;
+ return member_lookup;
+ } else if (member_lookup is FieldExpr){
+ FieldExpr fe = (FieldExpr) member_lookup;
+
+ fe.Instance = expr;
+
return member_lookup;
} else
//
// ie, for a Property Access, it should like call it
// and stuff.
- return null;
+ return member_lookup;
}
public override void Emit (EmitContext ec)
// </summary>
public class FieldExpr : Expression {
public readonly FieldInfo FieldInfo;
-
+ public Expression Instance;
+
public FieldExpr (FieldInfo fi)
{
FieldInfo = fi;
override public Expression Resolve (TypeContainer tc)
{
- // We are born in resolved state.
+ if (!FieldInfo.IsStatic){
+ if (Instance == null){
+ throw new Exception ("non-static FieldExpr without instance var\n" +
+ "You have to assign the Instance variable\n" +
+ "Of the FieldExpr to set this\n");
+ }
+
+ Instance = Instance.Resolve (tc);
+ if (Instance == null)
+ return null;
+
+ }
return this;
}
override public void Emit (EmitContext ec)
{
- // FIXME: Assert that this should not be reached?
+ ILGenerator ig = ec.ig;
+
+ if (FieldInfo.IsStatic)
+ ig.Emit (OpCodes.Ldsfld, FieldInfo);
+ else {
+ Instance.Emit (ec);
+
+ ig.Emit (OpCodes.Ldfld, FieldInfo);
+ }
}
}
public class CheckedExpr : Expression {
- public readonly Expression Expr;
+ public Expression Expr;
public CheckedExpr (Expression e)
{
public override Expression Resolve (TypeContainer tc)
{
- // FIXME : Implement !
+ Expr = Expr.Resolve (tc);
+
+ if (Expr == null)
+ return null;
+
+ eclass = Expr.ExprClass;
+ type = Expr.Type;
return this;
}
public override void Emit (EmitContext ec)
{
+ bool last_check = ec.CheckState;
+
+ ec.CheckState = true;
+
+ Expr.Emit (ec);
+
+ ec.CheckState = last_check;
}
}
public class UnCheckedExpr : Expression {
- public readonly Expression Expr;
+ public Expression Expr;
public UnCheckedExpr (Expression e)
{
public override Expression Resolve (TypeContainer tc)
{
- // FIXME : Implement !
+ Expr = Expr.Resolve (tc);
+
+ if (Expr == null)
+ return null;
+
+ eclass = Expr.ExprClass;
+ type = Expr.Type;
return this;
}
public override void Emit (EmitContext ec)
{
+ bool last_check = ec.CheckState;
+
+ ec.CheckState = false;
+
+ Expr.Emit (ec);
+
+ ec.CheckState = last_check;
}
}