namespace Mono.CSharp {
using System;
- using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
-
-#if NET_4_0
using System.Linq;
using SLE = System.Linq.Expressions;
-#endif
//
// This is an user operator expression, automatically created during
this.arguments = args;
this.expr_tree = expr_tree;
- type = TypeManager.TypeToCoreType (((MethodInfo) mg).ReturnType);
+ type = TypeManager.TypeToCoreType (((MethodSpec) mg).ReturnType);
eclass = ExprClass.Value;
this.loc = loc;
}
// Nothing to clone
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
//
// We are born fully resolved
mg.EmitCall (ec, arguments);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Call ((MethodInfo) mg, Arguments.MakeExpression (arguments, ctx));
+ var method = ((MethodSpec) mg).MetaInfo as MethodInfo;
+ return SLE.Expression.Call (method, Arguments.MakeExpression (arguments, ctx));
}
-#endif
public MethodGroupExpr Method {
get { return mg; }
loc = expr.Location;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return expr.Resolve (ec);
}
public Expression Expr;
Expression enum_conversion;
- public Unary (Operator op, Expression expr)
+ public Unary (Operator op, Expression expr, Location loc)
{
Oper = op;
Expr = expr;
- loc = expr.Location;
+ this.loc = loc;
}
// <summary>
if (expr_type == TypeManager.uint32_type) {
UIntLiteral uil = e as UIntLiteral;
if (uil != null) {
- if (uil.Value == 2147483648)
+ if (uil.Value == int.MaxValue + (uint) 1)
return new IntLiteral (int.MinValue, e.Location);
return new LongLiteral (-uil.Value, e.Location);
}
return expr;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (Oper == Operator.AddressOf) {
return ResolveAddressOf (ec);
}
if (TypeManager.IsNullableType (Expr.Type))
- return new Nullable.LiftedUnaryOperator (Oper, Expr).Resolve (ec);
+ return new Nullable.LiftedUnaryOperator (Oper, Expr, loc).Resolve (ec);
//
// Attempt to use a constant folding operation.
if (cexpr != null) {
cexpr = TryReduceConstant (ec, cexpr);
if (cexpr != null)
- return cexpr;
+ return cexpr.Resolve (ec);
}
Expression expr = ResolveOperator (ec, Expr);
throw new NotImplementedException (oper.ToString ());
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
var expr = Expr.MakeExpression (ctx);
return is_checked ? SLE.Expression.NegateChecked (expr) : SLE.Expression.Negate (expr);
case Operator.LogicalNot:
return SLE.Expression.Not (expr);
+#if NET_4_0
case Operator.OnesComplement:
return SLE.Expression.OnesComplement (expr);
+#endif
default:
throw new NotImplementedException (Oper.ToString ());
}
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
return null;
}
- if (!TypeManager.VerifyUnManaged (Expr.Type, loc)) {
+ if (!TypeManager.VerifyUnmanaged (ec.Compiler, Expr.Type, loc)) {
return null;
}
return DoResolve (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
/// classes (indexers require temporary access; overloaded require method)
///
/// </remarks>
- public class UnaryMutator : ExpressionStatement {
+ public class UnaryMutator : ExpressionStatement
+ {
+ class DynamicPostMutator : Expression, IAssignMethod
+ {
+ LocalTemporary temp;
+ Expression expr;
+
+ public DynamicPostMutator (Expression expr)
+ {
+ this.expr = expr;
+ this.type = expr.Type;
+ this.loc = expr.Location;
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext ec)
+ {
+ throw new NotImplementedException ("ET");
+ }
+
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ eclass = expr.eclass;
+ return this;
+ }
+
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+ {
+ expr.DoResolveLValue (ec, right_side);
+ return DoResolve (ec);
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ temp.Emit (ec);
+ }
+
+ public void Emit (EmitContext ec, bool leave_copy)
+ {
+ throw new NotImplementedException ();
+ }
+
+ //
+ // Emits target assignment using unmodified source value
+ //
+ public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+ {
+ //
+ // Allocate temporary variable to keep original value before it's modified
+ //
+ temp = new LocalTemporary (type);
+ expr.Emit (ec);
+ temp.Store (ec);
+
+ ((IAssignMethod) expr).EmitAssign (ec, source, false, prepare_for_load);
+
+ if (leave_copy)
+ Emit (ec);
+
+ temp.Release (ec);
+ temp = null;
+ }
+ }
+
[Flags]
public enum Mode : byte {
IsIncrement = 0,
// Holds the real operation
Expression operation;
- public UnaryMutator (Mode m, Expression e)
+ public UnaryMutator (Mode m, Expression e, Location loc)
{
mode = m;
- loc = e.Location;
+ this.loc = loc;
expr = e;
}
return new SimpleAssign (this, this).CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
return null;
if (TypeManager.IsDynamicType (expr.Type)) {
+ //
+ // Handle postfix unary operators using local
+ // temporary variable
+ //
+ if ((mode & Mode.IsPost) != 0)
+ expr = new DynamicPostMutator (expr);
+
Arguments args = new Arguments (1);
args.Add (new Argument (expr));
- return new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc).Resolve (ec);
+ return new SimpleAssign (expr, new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc)).Resolve (ec);
}
- eclass = ExprClass.Value;
-
if (TypeManager.IsNullableType (expr.Type))
return new Nullable.LiftedUnaryMutator (mode, expr, loc).Resolve (ec);
+ eclass = ExprClass.Value;
+ type = expr.Type;
return ResolveOperator (ec);
}
Expression ResolveOperator (ResolveContext ec)
{
- type = expr.Type;
-
if (expr is RuntimeValueExpression) {
operation = expr;
} else {
// TODO: Cache this based on type when using EmptyExpression in
// context cache
Binary.Operator op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition;
- operation = new Binary (op, operation, one);
+ operation = new Binary (op, operation, one, loc);
operation = operation.Resolve (ec);
- if (operation.Type != type)
+ if (operation != null && operation.Type != type)
operation = Convert.ExplicitNumericConversion (operation, type);
return this;
}
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
probe_type_expr = ProbeType.ResolveAsTypeTerminal (ec, false);
if (probe_type_expr == null)
ec.Report.Warning (184, 1, loc, "The given expression is never of the provided (`{0}') type",
TypeManager.CSharpName (probe_type_expr.Type));
- return ReducedExpression.Create (new BoolConstant (result, loc), this);
+ return ReducedExpression.Create (new BoolConstant (result, loc).Resolve (ec), this);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (base.DoResolve (ec) == null)
return null;
ig.Emit (OpCodes.Unbox_Any, type);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- // Because expr is modified
- if (eclass != ExprClass.Invalid)
- return this;
-
if (resolved_type == null) {
resolved_type = base.DoResolve (ec);
get { return target_type; }
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
this.arrayAccess = arrayAccess;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
return CreateExpressionFactoryCall (ec, "Constant", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
}
if (type.IsPointer)
- return new NullLiteral (Location).ConvertImplicitly (type);
+ return new NullLiteral (Location).ConvertImplicitly (ec, type);
if (TypeManager.IsReferenceType (type))
return new NullConstant (type, loc);
Constant c = New.Constantify (type);
if (c != null)
- return c;
+ return c.Resolve (ec);
eclass = ExprClass.Variable;
return this;
/// </summary>
public class Binary : Expression, IDynamicBinder
{
-
protected class PredefinedOperator {
protected readonly Type left;
protected readonly Type right;
if (left == TypeManager.decimal_type)
return b.ResolveUserOperator (ec, b.left.Type, b.right.Type);
+ var c = b.right as Constant;
+ if (c != null) {
+ if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr || b.oper == Operator.Subtraction))
+ return ReducedExpression.Create (b.left, b).Resolve (ec);
+ if ((b.oper == Operator.Multiply || b.oper == Operator.Division) && c.IsOneInteger)
+ return ReducedExpression.Create (b.left, b).Resolve (ec);
+ return b;
+ }
+
+ c = b.left as Constant;
+ if (c != null) {
+ if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr))
+ return ReducedExpression.Create (b.right, b).Resolve (ec);
+ if (b.oper == Operator.Multiply && c.IsOneInteger)
+ return ReducedExpression.Create (b.right, b).Resolve (ec);
+ return b;
+ }
+
return b;
}
//
// Start a new concat expression using converted expression
//
- return new StringConcat (b.loc, b.left, b.right).Resolve (ec);
+ return StringConcat.Create (ec, b.left, b.right, b.loc);
}
}
// b = b.left >> b.right & (0x1f|0x3f)
//
b.right = new Binary (Operator.BitwiseAnd,
- b.right, new IntConstant (right_mask, b.right.Location)).Resolve (ec);
+ b.right, new IntConstant (right_mask, b.right.Location), b.loc).Resolve (ec);
//
// Expression tree representation does not use & mask
//
b.right = ReducedExpression.Create (b.right, expr_tree_expr).Resolve (ec);
b.type = ReturnType;
+
+ //
+ // Optimize shift by 0
+ //
+ var c = b.right as Constant;
+ if (c != null && c.IsDefaultValue)
+ return ReducedExpression.Create (b.left, b).Resolve (ec);
+
return b;
}
}
static PredefinedOperator [] standard_operators;
static PredefinedOperator [] pointer_operators;
- public Binary (Operator oper, Expression left, Expression right, bool isCompound)
- : this (oper, left, right)
+ public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
+ : this (oper, left, right, loc)
{
this.is_compound = isCompound;
}
- public Binary (Operator oper, Expression left, Expression right)
+ public Binary (Operator oper, Expression left, Expression right, Location loc)
{
this.oper = oper;
this.left = left;
this.right = right;
- this.loc = left.Location;
+ this.loc = loc;
}
public Operator Oper {
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, Operator oper, Location loc)
{
- new Binary (oper, left, right).Error_OperatorCannotBeApplied (ec, left, right);
+ new Binary (oper, left, right, loc).Error_OperatorCannotBeApplied (ec, left, right);
}
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, string oper, Location loc)
static void CreatePointerOperatorsTable ()
{
- ArrayList temp = new ArrayList ();
+ var temp = new List<PredefinedPointerOperator> ();
//
// Pointer arithmetic:
//
temp.Add (new PredefinedPointerOperator (null, Operator.SubtractionMask, TypeManager.int64_type));
- pointer_operators = (PredefinedOperator []) temp.ToArray (typeof (PredefinedOperator));
+ pointer_operators = temp.ToArray ();
}
static void CreateStandardOperatorsTable ()
{
- ArrayList temp = new ArrayList ();
+ var temp = new List<PredefinedOperator> ();
Type bool_type = TypeManager.bool_type;
temp.Add (new PredefinedOperator (TypeManager.int32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
temp.Add (new PredefinedShiftOperator (TypeManager.int64_type, Operator.ShiftMask));
temp.Add (new PredefinedShiftOperator (TypeManager.uint64_type, Operator.ShiftMask));
- standard_operators = (PredefinedOperator []) temp.ToArray (typeof (PredefinedOperator));
+ standard_operators = temp.ToArray ();
}
//
// Rules used during binary numeric promotion
//
- static bool DoNumericPromotion (ref Expression prim_expr, ref Expression second_expr, Type type)
+ static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, Type type)
{
Expression temp;
Type etype;
Constant c = prim_expr as Constant;
if (c != null) {
- temp = c.ConvertImplicitly (type);
+ temp = c.ConvertImplicitly (rc, type);
if (temp != null) {
prim_expr = temp;
return true;
if (type != second_expr.Type) {
c = second_expr as Constant;
if (c != null)
- temp = c.ConvertImplicitly (type);
+ temp = c.ConvertImplicitly (rc, type);
else
temp = Convert.ImplicitNumericConversion (second_expr, type);
if (temp == null)
// A compile-time error occurs if the other operand is of type sbyte, short, int, or long
//
if (type == TypeManager.int32_type || type == TypeManager.int64_type ||
- type == TypeManager.sbyte_type || type == TypeManager.sbyte_type)
+ type == TypeManager.short_type || type == TypeManager.sbyte_type)
return false;
}
foreach (Type t in ConstantFold.binary_promotions) {
if (t == ltype)
- return t == rtype || DoNumericPromotion (ref right, ref left, t);
+ return t == rtype || DoNumericPromotion (ec, ref right, ref left, t);
if (t == rtype)
- return t == ltype || DoNumericPromotion (ref left, ref right, t);
+ return t == ltype || DoNumericPromotion (ec, ref left, ref right, t);
}
Type int32 = TypeManager.int32_type;
if (ltype != int32) {
Constant c = left as Constant;
if (c != null)
- temp = c.ConvertImplicitly (int32);
+ temp = c.ConvertImplicitly (ec, int32);
else
temp = Convert.ImplicitNumericConversion (left, int32);
if (rtype != int32) {
Constant c = right as Constant;
if (c != null)
- temp = c.ConvertImplicitly (int32);
+ temp = c.ConvertImplicitly (ec, int32);
else
temp = Convert.ImplicitNumericConversion (right, int32);
return true;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (left == null)
return null;
if (rc != null && lc != null) {
int prev_e = ec.Report.Errors;
- Expression e = ConstantFold.BinaryFold (
- ec, oper, lc, rc, loc);
+ Expression e = ConstantFold.BinaryFold (ec, oper, lc, rc, loc);
+ if (e != null)
+ e = e.Resolve (ec);
+
if (e != null || ec.Report.Errors != prev_e)
return e;
}
return expr;
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
var le = left.MakeExpression (ctx);
throw new NotImplementedException (oper.ToString ());
}
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
if (is_equality)
return ResolveUserOperator (ec, l, r);
- MethodInfo method;
+ MethodSpec method;
Arguments args = new Arguments (2);
args.Add (new Argument (left));
args.Add (new Argument (right));
method = TypeManager.delegate_remove_delegate_delegate;
}
- MethodGroupExpr mg = new MethodGroupExpr (new MemberInfo [] { method }, TypeManager.delegate_type, loc);
+ MethodGroupExpr mg = new MethodGroupExpr (new [] { method }, TypeManager.delegate_type, loc);
mg = mg.OverloadResolve (ec, ref args, false, loc);
return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l);
underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
if (left is Constant)
- left = ((Constant) left).ConvertExplicitly (false, underlying_type);
+ left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
else
left = EmptyCast.Create (left, underlying_type);
if (right is Constant)
- right = ((Constant) right).ConvertExplicitly (false, underlying_type);
+ right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
else
right = EmptyCast.Create (right, underlying_type);
} else if (lenum) {
}
if (left is Constant)
- left = ((Constant) left).ConvertExplicitly (false, underlying_type);
+ left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
else
left = EmptyCast.Create (left, underlying_type);
}
if (right is Constant)
- right = ((Constant) right).ConvertExplicitly (false, underlying_type);
+ right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
else
right = EmptyCast.Create (right, underlying_type);
new SideEffectConstant (lc, right, loc) :
new SideEffectConstant (rc, left, loc);
- return ReducedExpression.Create (side_effect, expr);
+ return ReducedExpression.Create (side_effect.Resolve (ec), expr);
}
}
(right is NullLiteral && IsBuildInEqualityOperator (l))) {
type = TypeManager.bool_type;
if (left is NullLiteral || right is NullLiteral)
- oper_expr = ReducedExpression.Create (this, oper_expr).Resolve (ec);
+ oper_expr = ReducedExpression.Create (this, oper_expr);
} else if (l != r) {
- MethodInfo mi = (MethodInfo) union;
+ var mi = union.BestCandidate;
//
// Two System.Delegate(s) are never equal
return;
}
- left.Emit (ec);
-
- //
- // Optimize zero-based operations
//
- // TODO: Implement more optimizations, but it should probably go to PredefinedOperators
+ // Optimize zero-based operations which cannot be optimized at expression level
//
- if ((oper & Operator.ShiftMask) != 0 || oper == Operator.Addition || oper == Operator.Subtraction) {
- Constant rc = right as Constant;
- if (rc != null && rc.IsDefaultValue) {
+ if (oper == Operator.Subtraction) {
+ var lc = left as IntegralConstant;
+ if (lc != null && lc.IsDefaultValue) {
+ right.Emit (ec);
+ ig.Emit (OpCodes.Neg);
return;
}
}
+ left.Emit (ec);
right.Emit (ec);
EmitOperatorOpcode (ec, oper, l);
public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args)
{
- Arguments binder_args = new Arguments (3);
+ Arguments binder_args = new Arguments (4);
MemberAccess sle = new MemberAccess (new MemberAccess (
new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc);
binder_args.Add (new Argument (new EnumConstant (new IntLiteral ((int) flags, loc), TypeManager.binder_flags)));
binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), GetOperatorExpressionTypeName (), loc)));
- binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc)));
+ binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));
+ binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (ec), loc)));
return new Invocation (DynamicExpressionStatement.GetBinder ("BinaryOperation", loc), binder_args);
}
public class StringConcat : Expression {
Arguments arguments;
- public StringConcat (Location loc, Expression left, Expression right)
+ public StringConcat (Expression left, Expression right, Location loc)
{
this.loc = loc;
type = TypeManager.string_type;
eclass = ExprClass.Value;
arguments = new Arguments (2);
- Append (left);
- Append (right);
+ }
+
+ public static StringConcat Create (ResolveContext rc, Expression left, Expression right, Location loc)
+ {
+ if (left.eclass == ExprClass.Unresolved || right.eclass == ExprClass.Unresolved)
+ throw new ArgumentException ();
+
+ var s = new StringConcat (left, right, loc);
+ s.Append (rc, left);
+ s.Append (rc, right);
+ return s;
}
public override Expression CreateExpressionTree (ResolveContext ec)
if (++pos == arguments.Count)
return expr;
- left = new Argument (new EmptyExpression (((MethodInfo)method).ReturnType));
+ left = new Argument (new EmptyExpression (method.BestCandidate.ReturnType));
return CreateExpressionAddCall (ec, left, expr, pos);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return this;
}
- public void Append (Expression operand)
+ void Append (ResolveContext rc, Expression operand)
{
//
// Constant folding
StringConstant last_expr_constant = last_argument.Expr as StringConstant;
if (last_expr_constant != null) {
last_argument.Expr = new StringConstant (
- last_expr_constant.Value + sc.Value, sc.Location);
+ last_expr_constant.Value + sc.Value, sc.Location).Resolve (rc);
return;
}
}
concat.Emit (ec);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
if (arguments.Count != 2)
var concat = TypeManager.string_type.GetMethod ("Concat", new[] { typeof (object), typeof (object) });
return SLE.Expression.Add (arguments[0].Expr.MakeExpression (ctx), arguments[1].Expr.MakeExpression (ctx), concat);
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
: base (oper_method, arguments, expr_tree, loc)
{
this.is_and = is_and;
+ eclass = ExprClass.Unresolved;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- MethodInfo method = (MethodInfo)mg;
+ var method = mg.BestCandidate;
type = TypeManager.TypeToCoreType (method.ReturnType);
- AParametersCollection pd = TypeManager.GetParameterData (method);
+ AParametersCollection pd = method.Parameters;
if (!TypeManager.IsEqual (type, type) || !TypeManager.IsEqual (type, pd.Types [0]) || !TypeManager.IsEqual (type, pd.Types [1])) {
ec.Report.Error (217, loc,
"A user-defined operator `{0}' must have parameters and return values of the same type in order to be applicable as a short circuit operator",
- TypeManager.CSharpSignature (method));
+ TypeManager.CSharpSignature (method.MetaInfo));
return null;
}
if (op_true == null || op_false == null) {
ec.Report.Error (218, loc,
"The type `{0}' must have operator `true' and operator `false' defined when `{1}' is used as a short circuit operator",
- TypeManager.CSharpName (type), TypeManager.CSharpSignature (method));
+ TypeManager.CSharpName (type), TypeManager.CSharpSignature (method.MetaInfo));
return null;
}
return null;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = ExprClass.Variable;
} else {
FieldExpr fe = left as FieldExpr;
if (fe != null)
- element = AttributeTester.GetFixedBuffer (fe.FieldInfo).ElementType;
+ element = ((FixedFieldSpec) (fe.Spec)).ElementType;
else
element = op_type;
}
left.Emit (ec);
- Constant right_const = right as Constant;
+ var right_const = right as Constant;
if (right_const != null) {
//
// Optimize 0-based arithmetic
if (right_const.IsDefaultValue)
return;
- if (size != 0) {
- // TODO: Should be the checks resolve context sensitive?
- ResolveContext rc = new ResolveContext (ec.MemberContext);
- right = ConstantFold.BinaryFold (rc, Binary.Operator.Multiply, new IntConstant (size, right.Location), right_const, loc);
- if (right == null)
- return;
- } else {
- ig.Emit (OpCodes.Sizeof, element);
- right = EmptyExpression.Null;
- }
+ if (size != 0)
+ right = new IntConstant (size, right.Location);
+ else
+ right = new SizeOf (new TypeExpression (element, right.Location), right.Location);
+
+ // TODO: Should be the checks resolve context sensitive?
+ ResolveContext rc = new ResolveContext (ec.MemberContext, ResolveContext.Options.UnsafeScope);
+ right = new Binary (Binary.Operator.Multiply, right, right_const, loc).Resolve (rc);
+ if (right == null)
+ return;
}
right.Emit (ec);
return base.CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// A boolean-expression is required to be of a type
// that can be implicitly converted to bool or of
return CreateExpressionFactoryCall (ec, "Condition", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
true_expr = true_expr.Resolve (ec);
Expression conv = Convert.ImplicitConversion (ec, true_expr, false_type, loc);
if (conv != null) {
//
- // Check if both can convert implicitl to each other's type
+ // Check if both can convert implicitly to each other's type
//
if (Convert.ImplicitConversion (ec, false_expr, true_type, loc) != null) {
- ec.Report.Error (172, loc,
- "Can not compute type of conditional expression " +
- "as `" + TypeManager.CSharpName (true_expr.Type) +
- "' and `" + TypeManager.CSharpName (false_expr.Type) +
- "' convert implicitly to each other");
+ ec.Report.Error (172, true_expr.Location,
+ "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other",
+ TypeManager.CSharpName (true_type), TypeManager.CSharpName (false_type));
return null;
}
type = false_type;
} else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) {
false_expr = conv;
} else {
- ec.Report.Error (173, loc,
+ ec.Report.Error (173, true_expr.Location,
"Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'",
TypeManager.CSharpName (true_type), TypeManager.CSharpName (false_type));
return null;
public abstract VariableInfo VariableInfo { get; }
#endregion
- public void AddressOf (EmitContext ec, AddressOp mode)
+ public virtual void AddressOf (EmitContext ec, AddressOp mode)
{
HoistedVariable hv = GetHoistedVariable (ec);
if (hv != null) {
public Block Block;
public LocalInfo local_info;
bool is_readonly;
- bool resolved; // TODO: merge with eclass
public LocalVariableReference (Block block, string name, Location l)
{
Expression DoResolveBase (ResolveContext ec)
{
- type = local_info.VariableType;
-
Expression e = Block.GetConstantExpression (Name);
if (e != null)
return e.Resolve (ec);
}
}
- resolved |= ec.DoFlowAnalysis;
eclass = ExprClass.Variable;
+ type = local_info.VariableType;
return this;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (resolved)
- return this;
-
ResolveLocalInfo ();
local_info.Used = true;
ResolveLocalInfo ();
// is out param
- if (right_side == EmptyExpression.OutAccess)
+ if (right_side == EmptyExpression.OutAccess.Instance)
local_info.Used = true;
// Infer implicitly typed local variable
if (is_readonly) {
int code;
string msg;
- if (right_side == EmptyExpression.OutAccess) {
+ if (right_side == EmptyExpression.OutAccess.Instance) {
code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
} else if (right_side == EmptyExpression.LValueMemberAccess) {
code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
continue;
//
- // Don't capture parameters inside same top level block
+ // Don't capture local parameters
//
- if (b == am.Block && !am.IsIterator)
+ if (b == ec.CurrentBlock.Toplevel && !am.IsIterator)
return true;
if (IsRef) {
return Name == pr.Name;
}
+
+ public override void AddressOf (EmitContext ec, AddressOp mode)
+ {
+ //
+ // ParameterReferences might already be a reference
+ //
+ if (IsRef) {
+ EmitLoad (ec);
+ return;
+ }
+
+ base.AddressOf (ec, mode);
+ }
protected override void CloneTo (CloneContext clonectx, Expression target)
{
// the type as it is expected, but when we generate the code, we generate
// the alternate kind of code.
//
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (!DoResolveBase (ec))
return null;
return CreateExpressionFactoryCall (ec, "Call", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- // Don't resolve already resolved expression
- if (eclass != ExprClass.Invalid)
- return this;
-
- Expression expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
- if (expr_resolved == null)
+ Expression member_expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+ if (member_expr == null)
return null;
//
if (arguments != null && !arguments_resolved)
arguments.Resolve (ec, out dynamic_arg);
- Type expr_type = expr_resolved.Type;
- mg = expr_resolved as MethodGroupExpr;
-
- if (dynamic_arg || TypeManager.IsDynamicType (expr_type)) {
- Arguments args;
- DynamicMemberBinder dmb = expr_resolved as DynamicMemberBinder;
- if (dmb != null) {
- args = dmb.Arguments;
- if (arguments != null)
- args.AddRange (arguments);
- } else if (mg == null) {
- if (arguments == null)
- args = new Arguments (1);
- else
- args = arguments;
-
- args.Insert (0, new Argument (expr_resolved));
- expr = null;
- } else {
- if (mg.IsBase) {
- ec.Report.Error (1971, loc,
- "The base call to method `{0}' cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access",
- mg.Name);
- return null;
- }
+ Type expr_type = member_expr.Type;
+ mg = member_expr as MethodGroupExpr;
- args = arguments;
+ bool dynamic_member = TypeManager.IsDynamicType (expr_type);
- if (mg.IsStatic != mg.IsInstance) {
- if (args == null)
- args = new Arguments (1);
+ if (!dynamic_member) {
+ Expression invoke = null;
- if (mg.IsStatic) {
- args.Insert (0, new Argument (new TypeOf (new TypeExpression (mg.DeclaringType, loc), loc).Resolve (ec), Argument.AType.DynamicStatic));
- } else {
- MemberAccess ma = expr as MemberAccess;
- if (ma != null)
- args.Insert (0, new Argument (ma.Left.Resolve (ec)));
- else
- args.Insert (0, new Argument (new This (loc).Resolve (ec)));
+ if (mg == null) {
+ if (expr_type != null && TypeManager.IsDelegateType (expr_type)) {
+ invoke = new DelegateInvocation (member_expr, arguments, loc);
+ invoke = invoke.Resolve (ec);
+ if (invoke == null || !dynamic_arg)
+ return invoke;
+ } else {
+ MemberExpr me = member_expr as MemberExpr;
+ if (me == null) {
+ member_expr.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc);
+ return null;
}
- }
- }
- return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
- }
+ mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
+ if (mg == null) {
+ ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
+ member_expr.GetSignatureForError ());
+ return null;
+ }
- if (mg == null) {
- if (expr_type != null && TypeManager.IsDelegateType (expr_type)){
- return (new DelegateInvocation (
- expr_resolved, arguments, loc)).Resolve (ec);
+ ((ExtensionMethodGroupExpr) mg).ExtensionExpression = me.InstanceExpression;
+ }
}
- MemberExpr me = expr_resolved as MemberExpr;
- if (me == null) {
- expr_resolved.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc);
- return null;
- }
-
- mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
- if (mg == null) {
- ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
- expr_resolved.GetSignatureForError ());
- return null;
+ if (invoke == null) {
+ mg = DoResolveOverload (ec);
+ if (mg == null)
+ return null;
}
-
- ((ExtensionMethodGroupExpr)mg).ExtensionExpression = me.InstanceExpression;
}
- mg = DoResolveOverload (ec);
- if (mg == null)
- return null;
+ if (dynamic_arg || dynamic_member)
+ return DoResolveDynamic (ec, member_expr);
- MethodInfo method = (MethodInfo)mg;
+ var method = mg.BestCandidate;
if (method != null) {
type = TypeManager.TypeToCoreType (method.ReturnType);
return this;
}
+ Expression DoResolveDynamic (ResolveContext ec, Expression memberExpr)
+ {
+ Arguments args;
+ DynamicMemberBinder dmb = memberExpr as DynamicMemberBinder;
+ if (dmb != null) {
+ args = dmb.Arguments;
+ if (arguments != null)
+ args.AddRange (arguments);
+ } else if (mg == null) {
+ if (arguments == null)
+ args = new Arguments (1);
+ else
+ args = arguments;
+
+ args.Insert (0, new Argument (memberExpr));
+ this.expr = null;
+ } else {
+ if (mg.IsBase) {
+ ec.Report.Error (1971, loc,
+ "The base call to method `{0}' cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access",
+ mg.Name);
+ return null;
+ }
+
+ args = arguments;
+
+ if (mg.IsStatic != mg.IsInstance) {
+ if (args == null)
+ args = new Arguments (1);
+
+ if (mg.IsStatic) {
+ args.Insert (0, new Argument (new TypeOf (new TypeExpression (mg.DeclaringType, loc), loc).Resolve (ec), Argument.AType.DynamicTypeName));
+ } else {
+ MemberAccess ma = expr as MemberAccess;
+ if (ma != null)
+ args.Insert (0, new Argument (ma.Left.Resolve (ec)));
+ else
+ args.Insert (0, new Argument (new This (loc).Resolve (ec)));
+ }
+ }
+ }
+
+ return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
+ }
+
protected virtual MethodGroupExpr DoResolveOverload (ResolveContext ec)
{
return mg.OverloadResolve (ec, ref arguments, false, loc);
}
- public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodBase method, Location loc)
+ public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodSpec method, Location loc)
{
- if (!TypeManager.IsSpecialMethod (method))
+ if (!TypeManager.IsSpecialMethod (method.MetaInfo))
return false;
- ec.Report.SymbolRelatedToPreviousError (method);
+ if (ec.HasSet (ResolveContext.Options.InvokeSpecialName))
+ return false;
+
+ ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
ec.Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
- TypeManager.CSharpSignature (method, true));
+ TypeManager.CSharpSignature (method.MetaInfo, true));
return true;
}
- static Type[] GetVarargsTypes (MethodBase mb, Arguments arguments)
+ static Type[] GetVarargsTypes (MethodSpec mb, Arguments arguments)
{
- AParametersCollection pd = TypeManager.GetParameterData (mb);
+ AParametersCollection pd = mb.Parameters;
Argument a = arguments [pd.Count - 1];
Arglist list = (Arglist) a.Expr;
/// <summary>
/// This checks the ConditionalAttribute on the method
/// </summary>
- public static bool IsMethodExcluded (MethodBase method, Location loc)
+ public static bool IsMethodExcluded (MethodSpec method, Location loc)
{
if (method.IsConstructor)
return false;
- method = TypeManager.DropGenericMethodArguments (method);
- if (TypeManager.IsBeingCompiled (method)) {
- IMethodData md = TypeManager.GetMethod (method);
+ var mb = TypeManager.DropGenericMethodArguments (method.MetaInfo);
+ if (TypeManager.IsBeingCompiled (mb)) {
+ IMethodData md = TypeManager.GetMethod (mb);
if (md != null)
return md.IsExcluded ();
return false;
}
- return AttributeTester.IsConditionalMethodExcluded (method, loc);
+ return AttributeTester.IsConditionalMethodExcluded (mb, loc);
}
/// <remarks>
/// </remarks>
public static void EmitCall (EmitContext ec, bool is_base,
Expression instance_expr,
- MethodBase method, Arguments Arguments, Location loc)
+ MethodSpec method, Arguments Arguments, Location loc)
{
EmitCall (ec, is_base, instance_expr, method, Arguments, loc, false, false);
}
// only have been evaluated once.
public static void EmitCall (EmitContext ec, bool is_base,
Expression instance_expr,
- MethodBase method, Arguments Arguments, Location loc,
+ MethodSpec method, Arguments Arguments, Location loc,
bool dup_args, bool omit_args)
{
ILGenerator ig = ec.ig;
ig.Emit (OpCodes.Constrained, instance_expr.Type);
}
- if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
+ if ((method.MetaInfo.CallingConvention & CallingConventions.VarArgs) != 0) {
Type[] varargs_types = GetVarargsTypes (method, Arguments);
- ig.EmitCall (call_op, (MethodInfo) method, varargs_types);
+ ig.EmitCall (call_op, (MethodInfo) method.MetaInfo, varargs_types);
return;
}
// and DoFoo is not virtual, you can omit the callvirt,
// because you don't need the null checking behavior.
//
- if (method is MethodInfo)
- ig.Emit (call_op, (MethodInfo) method);
+ if (method.IsConstructor)
+ ig.Emit (call_op, (ConstructorInfo) method.MetaInfo);
else
- ig.Emit (call_op, (ConstructorInfo) method);
+ ig.Emit (call_op, (MethodInfo) method.MetaInfo);
}
public override void Emit (EmitContext ec)
target.expr = expr.Clone (clonectx);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return MakeExpression (ctx, mg.InstanceExpression, (MethodInfo) mg, arguments);
+ return MakeExpression (ctx, mg.InstanceExpression, (MethodSpec) mg, arguments);
}
- public static SLE.Expression MakeExpression (BuilderContext ctx, Expression instance, MethodInfo mi, Arguments args)
+ public static SLE.Expression MakeExpression (BuilderContext ctx, Expression instance, MethodSpec mi, Arguments args)
{
var instance_expr = instance == null ? null : instance.MakeExpression (ctx);
- SLE.Expression expr = SLE.Expression.Call (instance_expr, mi,
- Arguments.MakeExpression (args, ctx));
-
- if (mi.ReturnType == typeof (void)) {
- expr = SLE.Expression.Block (
- expr,
- SLE.Expression.Default (typeof (object)));
- }
-
- return expr;
+ return SLE.Expression.Call (instance_expr, (MethodInfo) mi.MetaInfo, Arguments.MakeExpression (args, ctx));
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
/// Implements the new expression
/// </summary>
public class New : ExpressionStatement, IMemoryLocation {
- Arguments Arguments;
+ protected Arguments Arguments;
//
// During bootstrap, it contains the RequestedType,
// but if `type' is not null, it *might* contain a NewDelegate
// (because of field multi-initialization)
//
- Expression RequestedType;
+ protected Expression RequestedType;
- MethodGroupExpr method;
+ protected MethodGroupExpr method;
bool is_type_parameter;
args = new Arguments (1);
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
} else {
- args = Arguments.CreateForExpressionTree (ec, Arguments,
+ args = Arguments.CreateForExpressionTree (ec,
+ Arguments,
method.CreateExpressionTree (ec));
}
return CreateExpressionFactoryCall (ec, "New", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
//
// The New DoResolve might be called twice when initializing field
if (Arguments == null) {
Constant c = Constantify (type);
if (c != null)
- return ReducedExpression.Create (c, this);
+ return ReducedExpression.Create (c.Resolve (ec), this);
}
if (TypeManager.IsDelegateType (type)) {
}
if (TypeManager.activator_create_instance == null) {
- Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", Kind.Class, true);
+ Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
if (activator_type != null) {
TypeManager.activator_create_instance = TypeManager.GetPredefinedMethod (
activator_type, "CreateInstance", loc, Type.EmptyTypes);
Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName,
MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+ bool dynamic;
if (Arguments != null) {
- bool dynamic;
Arguments.Resolve (ec, out dynamic);
-
- if (dynamic) {
- Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec)));
- return new DynamicInvocation (new SimpleName (ConstructorInfo.ConstructorName, loc), Arguments, type, loc).Resolve (ec);
- }
+ } else {
+ dynamic = false;
}
if (ml == null)
if (method == null)
return null;
+ if (dynamic) {
+ Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec), Argument.AType.DynamicTypeName));
+ return new DynamicConstructorBinder (type, Arguments, loc).Resolve (ec);
+ }
+
return this;
}
{
ILGenerator ig = ec.ig;
- MethodInfo ci = TypeManager.activator_create_instance.MakeGenericMethod (
- new Type [] { type });
+ MethodInfo ci = (MethodInfo) TypeManager.activator_create_instance.MetaInfo;
+ ci = ci.MakeGenericMethod (new Type [] { type });
GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
if (gc.HasReferenceTypeConstraint || gc.HasClassConstraint) {
}
if (vr != null) {
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+ ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
return false;
}
}
if (is_type_parameter)
return DoEmitTypeParameter (ec);
- ConstructorInfo ci = (ConstructorInfo) method;
+ ConstructorInfo ci = (ConstructorInfo) method.BestCandidate.MetaInfo;
#if MS_COMPATIBLE
if (TypeManager.IsGenericType (type) && type.IsGenericTypeDefinition)
ci = TypeBuilder.GetConstructor (type, ci);
ec.ig.Emit (OpCodes.Pop);
}
- public bool IsDefaultValueType {
- get {
- return TypeManager.IsValueType (type) && !HasInitializer && Arguments == null;
- }
- }
-
public virtual bool HasInitializer {
get {
return false;
if (Arguments != null)
Arguments.Emit (ec);
- ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+ ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
}
value_target.AddressOf (ec, mode);
}
}
+ public override SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.MetaInfo, Arguments.MakeExpression (Arguments, ctx));
+ }
+
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
if (method != null) {
}
}
+ public class ArrayInitializer : ShimExpression
+ {
+ List<Expression> elements;
+
+ public ArrayInitializer (List<Expression> init, Location loc)
+ : base (null)
+ {
+ elements = init;
+ }
+
+ public ArrayInitializer (int count, Location loc)
+ : base (null)
+ {
+ elements = new List<Expression> (count);
+ }
+
+ public ArrayInitializer (Location loc)
+ : this (4, loc)
+ {
+ }
+
+ public void Add (Expression expr)
+ {
+ elements.Add (expr);
+ }
+
+ protected override void CloneTo (CloneContext clonectx, Expression t)
+ {
+ var target = (ArrayInitializer) t;
+
+ target.elements = new List<Expression> (elements.Count);
+ foreach (var element in elements)
+ target.elements.Add (element.Clone (clonectx));
+
+ base.CloneTo (clonectx, t);
+ }
+
+ public int Count {
+ get { return elements.Count; }
+ }
+
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public Expression this [int index] {
+ get { return elements [index]; }
+ }
+ }
+
/// <summary>
/// 14.5.10.2: Represents an array creation expression.
/// </summary>
/// initialization data and the other which does not need dimensions
/// specified but where initialization data is mandatory.
/// </remarks>
- public class ArrayCreation : Expression {
+ class ArrayCreation : Expression
+ {
FullNamedExpression requested_base_type;
- ArrayList initializers;
+ ArrayInitializer initializers;
//
// The list of Argument types.
// This is used to construct the `newarray' or constructor signature
//
- protected ArrayList arguments;
+ protected List<Expression> arguments;
protected Type array_element_type;
bool expect_initializers = false;
protected List<Expression> array_data;
- IDictionary bounds;
+ Dictionary<int, int> bounds;
// The number of constants in array initializers
int const_initializers_count;
bool only_constant_initializers;
-
- public ArrayCreation (FullNamedExpression requested_base_type, ArrayList exprs, string rank, ArrayList initializers, Location l)
+
+ public ArrayCreation (FullNamedExpression requested_base_type, List<Expression> exprs, string rank, ArrayInitializer initializers, Location l)
{
this.requested_base_type = requested_base_type;
this.initializers = initializers;
this.rank = rank;
loc = l;
- arguments = new ArrayList (exprs.Count);
-
- foreach (Expression e in exprs) {
- arguments.Add (e);
- num_arguments++;
- }
+ arguments = new List<Expression> (exprs);
+ num_arguments = arguments.Count;
}
- public ArrayCreation (FullNamedExpression requested_base_type, string rank, ArrayList initializers, Location l)
+ public ArrayCreation (FullNamedExpression requested_base_type, string rank, ArrayInitializer initializers, Location l)
{
this.requested_base_type = requested_base_type;
this.initializers = initializers;
ec.Report.Error (248, loc, "Cannot create an array with a negative size");
}
- bool CheckIndices (ResolveContext ec, ArrayList probe, int idx, bool specified_dims, int child_bounds)
+ bool CheckIndices (ResolveContext ec, ArrayInitializer probe, int idx, bool specified_dims, int child_bounds)
{
if (specified_dims) {
- Expression a = (Expression) arguments [idx];
+ Expression a = arguments [idx];
a = a.Resolve (ec);
if (a == null)
return false;
only_constant_initializers = true;
for (int i = 0; i < probe.Count; ++i) {
- object o = probe [i];
- if (o is ArrayList) {
- ArrayList sub_probe = o as ArrayList;
+ var o = probe [i];
+ if (o is ArrayInitializer) {
+ var sub_probe = o as ArrayInitializer;
if (idx + 1 >= dimensions){
ec.Report.Error (623, loc, "Array initializers can only be used in a variable or field initializer. Try using a new expression instead");
return false;
if (!ret)
return false;
} else if (child_bounds > 1) {
- ec.Report.Error (846, ((Expression) o).Location, "A nested array initializer was expected");
+ ec.Report.Error (846, o.Location, "A nested array initializer was expected");
} else {
- Expression element = ResolveArrayElement (ec, (Expression) o);
+ Expression element = ResolveArrayElement (ec, o);
if (element == null)
continue;
for (int i = 0; i < array_data.Count; ++i) {
Expression e = array_data [i];
if (e == null)
- e = Convert.ImplicitConversion (ec, (Expression) initializers [i], array_element_type, loc);
+ e = Convert.ImplicitConversion (ec, initializers [i], array_element_type, loc);
args.Add (new Argument (e.CreateExpressionTree (ec)));
}
public void UpdateIndices ()
{
int i = 0;
- for (ArrayList probe = initializers; probe != null;) {
- if (probe.Count > 0 && probe [0] is ArrayList) {
+ for (var probe = initializers; probe != null;) {
+ if (probe.Count > 0 && probe [0] is ArrayInitializer) {
Expression e = new IntConstant (probe.Count, Location.Null);
arguments.Add (e);
- bounds [i++] = probe.Count;
-
- probe = (ArrayList) probe [0];
+ bounds [i++] = probe.Count;
+
+ probe = (ArrayInitializer) probe[0];
} else {
Expression e = new IntConstant (probe.Count, Location.Null);
// will need to store them in the byte blob later
//
array_data = new List<Expression> ();
- bounds = new System.Collections.Specialized.HybridDictionary ();
+ bounds = new Dictionary<int, int> ();
if (arguments != null)
return CheckIndices (ec, initializers, 0, true, dimensions);
- arguments = new ArrayList ();
+ arguments = new List<Expression> ();
if (!CheckIndices (ec, initializers, 0, false, dimensions))
return false;
//
bool ResolveArrayType (ResolveContext ec)
{
- if (requested_base_type == null) {
- ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
- return false;
- }
-
if (requested_base_type is VarExpr) {
ec.Report.Error (820, loc, "An implicitly typed local variable declarator cannot use an array initializer");
return false;
return false;
type = array_type_expr.Type;
+ if (!type.IsArray) {
+ ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
+ return false;
+ }
+
array_element_type = TypeManager.GetElementType (type);
dimensions = type.GetArrayRank ();
return true;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (type != null)
return this;
return null;
for (int i = 0; i < arguments.Count; ++i) {
- Expression e = ((Expression) arguments[i]).Resolve (ec);
+ Expression e = arguments[i].Resolve (ec);
if (e == null)
continue;
return this;
}
- MethodInfo GetArrayMethod (int arguments)
+ MethodInfo GetArrayMethod (EmitContext ec, int arguments)
{
ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
arg_types);
if (mi == null) {
- RootContext.ToplevelTypes.Compiler.Report.Error (-6, "New invocation: Can not find a constructor for " +
+ ec.Report.Error (-6, "New invocation: Can not find a constructor for " +
"this argument list");
return null;
}
ig.Emit (OpCodes.Dup);
ig.Emit (OpCodes.Ldtoken, fb);
- ig.Emit (OpCodes.Call,
- TypeManager.void_initializearray_array_fieldhandle);
+ ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_initializearray_array_fieldhandle.MetaInfo);
}
//
for (int i = 0; i < array_data.Count; i++){
- Expression e = (Expression)array_data [i];
+ Expression e = array_data [i];
// Constant can be initialized via StaticInitializer
if (e != null && !(!emitConstants && e is Constant)) {
//
for (int j = dims - 1; j >= 0; j--){
current_pos [j]++;
- if (current_pos [j] < (int) bounds [j])
+ if (current_pos [j] < bounds [j])
break;
current_pos [j] = 0;
}
if (arguments.Count == 1)
ig.Emit (OpCodes.Newarr, TypeManager.TypeToReflectionType (array_element_type));
else {
- ig.Emit (OpCodes.Newobj, GetArrayMethod (arguments.Count));
+ ig.Emit (OpCodes.Newobj, GetArrayMethod (ec, arguments.Count));
}
if (initializers == null)
return;
- // Emit static initializer for arrays which have contain more than 4 items and
+ // Emit static initializer for arrays which have contain more than 2 items and
// the static initializer will initialize at least 25% of array values.
// NOTE: const_initializers_count does not contain default constant values.
- if (const_initializers_count >= 4 && const_initializers_count * 4 > (array_data.Count) &&
+ if (const_initializers_count > 2 && const_initializers_count * 4 > (array_data.Count) &&
(TypeManager.IsPrimitiveType (array_element_type) || TypeManager.IsEnumType (array_element_type))) {
EmitStaticInitializers (ec);
}
if (array_data == null) {
- Expression arg = (Expression) arguments[0];
+ Expression arg = arguments [0];
object arg_value;
if (arg.GetAttributableValue (ec, arg.Type, out arg_value) && arg_value is int && (int)arg_value == 0) {
value = Array.CreateInstance (array_element_type, 0);
object element_value;
for (int i = 0; i < ret.Length; ++i)
{
- Expression e = (Expression)array_data [i];
+ Expression e = array_data [i];
// Is null when an initializer is optimized (value == predefined value)
if (e == null)
target.requested_base_type = (FullNamedExpression)requested_base_type.Clone (clonectx);
if (arguments != null){
- target.arguments = new ArrayList (arguments.Count);
+ target.arguments = new List<Expression> (arguments.Count);
foreach (Expression e in arguments)
target.arguments.Add (e.Clone (clonectx));
}
- if (initializers != null){
- target.initializers = new ArrayList (initializers.Count);
- foreach (object initializer in initializers)
- if (initializer is ArrayList) {
- ArrayList this_al = (ArrayList)initializer;
- ArrayList al = new ArrayList (this_al.Count);
- target.initializers.Add (al);
- foreach (Expression e in this_al)
- al.Add (e.Clone (clonectx));
- } else {
- target.initializers.Add (((Expression)initializer).Clone (clonectx));
- }
- }
+ if (initializers != null)
+ target.initializers = (ArrayInitializer) initializers.Clone (clonectx);
}
}
//
// Represents an implicitly typed array epxression
//
- public class ImplicitlyTypedArrayCreation : ArrayCreation
+ class ImplicitlyTypedArrayCreation : ArrayCreation
{
- public ImplicitlyTypedArrayCreation (string rank, ArrayList initializers, Location loc)
+ public ImplicitlyTypedArrayCreation (string rank, ArrayInitializer initializers, Location loc)
: base (null, rank, initializers, loc)
{
if (rank.Length > 2) {
}
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (type != null)
return this;
this.type = type;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = ExprClass.Variable;
if (type == null)
public bool ResolveBase (ResolveContext ec)
{
- if (eclass != ExprClass.Invalid)
- return true;
-
eclass = ExprClass.Variable;
type = ec.CurrentType;
return CreateExpressionFactoryCall (ec, "Constant", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
ResolveBase (ec);
return this;
if (ec.CurrentType.IsClass){
if (right_side == EmptyExpression.UnaryAddress)
ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only");
- else if (right_side == EmptyExpression.OutAccess)
+ else if (right_side == EmptyExpression.OutAccess.Instance)
ec.Report.Error (1605, loc, "Cannot pass `this' as a ref or out argument because it is read-only");
else
ec.Report.Error (1604, loc, "Cannot assign to `this' because it is read-only");
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = ExprClass.Variable;
type = TypeManager.runtime_argument_handle_type;
return null;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = ExprClass.Variable;
type = InternalType.Arglist;
return CreateExpressionFactoryCall (ec, "Constant", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (eclass != ExprClass.Invalid)
- return this;
-
TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return null;
public override void Emit (EmitContext ec)
{
ec.ig.Emit (OpCodes.Ldtoken, TypeManager.TypeToReflectionType (typearg));
- ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
+ ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.system_type_get_type_from_handle.MetaInfo);
}
public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
- typearg = storey.MutateType (typearg);
+ if (!TypeManager.IsGenericTypeDefinition (typearg))
+ typearg = storey.MutateType (typearg);
}
public Type TypeArgument {
loc = l;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
type = TypeManager.type_type;
typearg = TypeManager.void_type;
}
}
- class TypeOfMethod : TypeOfMember
+ class TypeOfMethod : TypeOfMember<MethodSpec>
{
- public TypeOfMethod (MethodBase method, Location loc)
+ public TypeOfMethod (MethodSpec method, Location loc)
: base (method, loc)
{
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (member is MethodInfo) {
- type = TypeManager.methodinfo_type;
+ if (member.IsConstructor) {
+ type = TypeManager.ctorinfo_type;
if (type == null)
- type = TypeManager.methodinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "MethodInfo", Kind.Class, true);
+ type = TypeManager.ctorinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "ConstructorInfo", MemberKind.Class, true);
} else {
- type = TypeManager.ctorinfo_type;
+ type = TypeManager.methodinfo_type;
if (type == null)
- type = TypeManager.ctorinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "ConstructorInfo", Kind.Class, true);
+ type = TypeManager.methodinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "MethodInfo", MemberKind.Class, true);
}
return base.DoResolve (ec);
public override void Emit (EmitContext ec)
{
- if (member is ConstructorInfo)
- ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member);
+ if (member.IsConstructor)
+ ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member.MetaInfo);
else
- ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member);
+ ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member.MetaInfo);
base.Emit (ec);
ec.ig.Emit (OpCodes.Castclass, type);
get { return "RuntimeMethodHandle"; }
}
- protected override MethodInfo TypeFromHandle {
+ protected override MethodSpec TypeFromHandle {
get {
return TypeManager.methodbase_get_type_from_handle;
}
}
}
- protected override MethodInfo TypeFromHandleGeneric {
+ protected override MethodSpec TypeFromHandleGeneric {
get {
return TypeManager.methodbase_get_type_from_handle_generic;
}
}
}
- abstract class TypeOfMember : Expression
+ abstract class TypeOfMember<T> : Expression where T : MemberSpec
{
- protected readonly MemberInfo member;
+ protected readonly T member;
- protected TypeOfMember (MemberInfo member, Location loc)
+ protected TypeOfMember (T member, Location loc)
{
this.member = member;
this.loc = loc;
return CreateExpressionFactoryCall (ec, "Constant", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
- MethodInfo mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
+ var mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
if (mi == null) {
- Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, Kind.Class, true);
- Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, Kind.Class, true);
+ Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
+ Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Class, true);
if (t == null || handle_type == null)
return null;
public override void Emit (EmitContext ec)
{
bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
- MethodInfo mi;
+ MethodSpec mi;
if (is_generic) {
mi = TypeFromHandleGeneric;
ec.ig.Emit (OpCodes.Ldtoken, member.DeclaringType);
mi = TypeFromHandle;
}
- ec.ig.Emit (OpCodes.Call, mi);
+ ec.ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
}
protected abstract string GetMethodName { get; }
protected abstract string RuntimeHandleName { get; }
- protected abstract MethodInfo TypeFromHandle { get; set; }
- protected abstract MethodInfo TypeFromHandleGeneric { get; set; }
+ protected abstract MethodSpec TypeFromHandle { get; set; }
+ protected abstract MethodSpec TypeFromHandleGeneric { get; set; }
protected abstract string TypeName { get; }
}
- class TypeOfField : TypeOfMember
+ class TypeOfField : TypeOfMember<FieldSpec>
{
- public TypeOfField (FieldInfo field, Location loc)
+ public TypeOfField (FieldSpec field, Location loc)
: base (field, loc)
{
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (TypeManager.fieldinfo_type == null)
- TypeManager.fieldinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, Kind.Class, true);
+ TypeManager.fieldinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
type = TypeManager.fieldinfo_type;
return base.DoResolve (ec);
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldtoken, (FieldInfo) member);
+ ec.ig.Emit (OpCodes.Ldtoken, member.MetaInfo);
base.Emit (ec);
}
get { return "RuntimeFieldHandle"; }
}
- protected override MethodInfo TypeFromHandle {
+ protected override MethodSpec TypeFromHandle {
get {
return TypeManager.fieldinfo_get_field_from_handle;
}
}
}
- protected override MethodInfo TypeFromHandleGeneric {
+ protected override MethodSpec TypeFromHandleGeneric {
get {
return TypeManager.fieldinfo_get_field_from_handle_generic;
}
return null;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
int size_of = GetTypeSize (type_queried);
if (size_of > 0) {
- return new IntConstant (size_of, loc);
+ return new IntConstant (size_of, loc).Resolve (ec);
}
- if (!TypeManager.VerifyUnManaged (type_queried, loc)){
+ if (!TypeManager.VerifyUnmanaged (ec.Compiler, type_queried, loc)){
return null;
}
return fne;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return ResolveAsTypeStep (ec, false);
}
//
SimpleName original = expr as SimpleName;
- Expression expr_resolved = expr.Resolve (ec,
- ResolveFlags.VariableOrValue | ResolveFlags.Type |
- ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis);
+ Expression expr_resolved;
+ using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
+ expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.Intermediate);
+ }
if (expr_resolved == null)
return null;
FullNamedExpression retval = ns.Lookup (ec.Compiler, LookupIdentifier, loc);
if (retval == null)
- ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec.Report);
+ ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec);
else if (targs != null)
retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
Type expr_type = expr_resolved.Type;
if (TypeManager.IsDynamicType (expr_type)) {
- Arguments args = new Arguments (2);
+ Arguments args = new Arguments (1);
args.Add (new Argument (expr_resolved.Resolve (ec)));
+ expr = new DynamicMemberBinder (Name, args, loc);
if (right_side != null)
- args.Add (new Argument (right_side));
+ return expr.DoResolveLValue (ec, right_side);
- return new DynamicMemberBinder (right_side != null, Name, args, loc).Resolve (ec);
+ return expr.Resolve (ec);
}
if (expr_type.IsPointer || expr_type == TypeManager.void_type ||
ex_method_lookup.SetTypeArguments (ec, targs);
}
- return ex_method_lookup.DoResolve (ec);
+ return ex_method_lookup.Resolve (ec);
}
}
me.SetTypeArguments (ec, targs);
}
- if (original != null && !TypeManager.IsValueType (expr_type)) {
+ if (original != null && (!TypeManager.IsValueType (expr_type) || me is PropertyExpr)) {
if (me.IsInstance) {
LocalVariableReference var = expr_resolved as LocalVariableReference;
if (var != null && !var.VerifyAssigned (ec))
if (right_side != null)
return me.DoResolveLValue (ec, right_side);
else
- return me.DoResolve (ec);
+ return me.Resolve (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return DoResolve (ec, null);
}
FullNamedExpression retval = ns.Lookup (rc.Compiler, LookupIdentifier, loc);
if (retval == null && !silent)
- ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc.Compiler.Report);
+ ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc);
else if (targs != null)
retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
{
- if (RootContext.Version > LanguageVersion.ISO_2 &&
+ if (RootContext.Version > LanguageVersion.ISO_2 && !ec.Compiler.IsRuntimeBinder &&
((expr.eclass & (ExprClass.Value | ExprClass.Variable)) != 0)) {
ec.Report.Error (1061, loc, "Type `{0}' does not contain a definition for `{1}' and no " +
"extension method `{1}' of type `{0}' could be found " +
return Expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
using (ec.With (ResolveContext.Options.AllCheckStateFlags, true))
Expr = Expr.Resolve (ec);
Expr.EmitBranchable (ec, target, on_true);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
using (ctx.With (BuilderContext.Options.AllCheckStateFlags, true)) {
return Expr.MakeExpression (ctx);
}
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
return Expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
using (ec.With (ResolveContext.Options.AllCheckStateFlags, false))
Expr = Expr.Resolve (ec);
return new Indirection (p, loc).Resolve (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
Expr = Expr.Resolve (ec);
if (Expr == null)
FieldExpr fe = Expr as FieldExpr;
if (fe != null) {
- IFixedBuffer ff = AttributeTester.GetFixedBuffer (fe.FieldInfo);
+ var ff = fe.Spec as FixedFieldSpec;
if (ff != null) {
return MakePointerAccess (ec, ff.ElementType);
}
public static void Error_NamedArgument (NamedArgument na, Report Report)
{
- Report.Error (1742, na.Name.Location, "An element access expression cannot use named argument");
+ Report.Error (1742, na.Location, "An element access expression cannot use named argument");
}
public override string GetSignatureForError ()
return DoResolve (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
-#if false
- ExprClass eclass = ea.Expr.eclass;
-
- // As long as the type is valid
- if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
- eclass == ExprClass.Value)) {
- ea.Expr.Error_UnexpectedKind ("variable or value");
- return null;
- }
-#endif
-
- if (eclass != ExprClass.Invalid)
- return this;
-
// dynamic is used per argument in ConvertExpressionToArrayIndex case
bool dynamic;
ea.Arguments.Resolve (ec, out dynamic);
ea.Expr.MakeExpression (ctx),
Arguments.MakeExpression (ea.Arguments, ctx));
}
+#endif
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
ea.Expr.MakeExpression (ctx),
Arguments.MakeExpression (ea.Arguments, ctx));
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
public IndexerMethodGroupExpr (Indexers indexers, Location loc)
: base (null, loc)
{
- Methods = (MethodBase []) indexers.Methods.ToArray (typeof (MethodBase));
+ Methods = indexers.Methods.ToArray ();
}
public override string Name {
}
}
- protected override int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
+ protected override int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
{
//
// Here is the trick, decrease number of arguments by 1 when only
class Indexers
{
// Contains either property getter or setter
- public ArrayList Methods;
- public ArrayList Properties;
+ public List<MethodSpec> Methods;
+ public List<PropertyInfo> Properties;
Indexers ()
{
accessor = property.GetSetMethod (true);
if (Methods == null) {
- Methods = new ArrayList ();
- Properties = new ArrayList ();
+ Methods = new List<MethodSpec> ();
+ Properties = new List<PropertyInfo> ();
}
- Methods.Add (accessor);
+ Methods.Add (Import.CreateMethod (accessor));
Properties.Add (property);
}
}
//
// Points to our "data" repository
//
- MethodInfo get, set;
+ MethodSpec get, set;
bool is_base_indexer;
bool prepared;
LocalTemporary temp;
{
this.instance_expr = instance_expr;
this.is_base_indexer = is_base_indexer;
- this.eclass = ExprClass.Value;
this.loc = loc;
}
current_type = ec.CurrentType;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return ResolveAccessor (ec, null);
}
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
- if (right_side == EmptyExpression.OutAccess) {
- ec.Report.Error (206, loc,
- "A property or indexer may not be passed as an out or ref parameter");
+ if (right_side == EmptyExpression.OutAccess.Instance) {
+ right_side.DoResolveLValue (ec, this);
return null;
}
{
CommonResolve (ec);
+ MethodGroupExpr mg;
+ Indexers ilist;
bool dynamic;
+
arguments.Resolve (ec, out dynamic);
- if (dynamic || TypeManager.IsDynamicType (indexer_type)) {
- int additional = right_side == null ? 1 : 2;
- Arguments args = new Arguments (arguments.Count + additional);
+
+ if (TypeManager.IsDynamicType (indexer_type)) {
+ dynamic = true;
+ mg = null;
+ ilist = null;
+ } else {
+ ilist = Indexers.GetIndexersForType (current_type, indexer_type);
+ if (ilist.Methods == null) {
+ ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
+ TypeManager.CSharpName (indexer_type));
+ return null;
+ }
+
+ mg = new IndexerMethodGroupExpr (ilist, loc);
+ mg = mg.OverloadResolve (ec, ref arguments, false, loc);
+ if (mg == null)
+ return null;
+ }
+
+ if (dynamic) {
+ Arguments args = new Arguments (arguments.Count + 1);
if (is_base_indexer) {
ec.Report.Error (1972, loc, "The indexer base access cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access");
} else {
args.Add (new Argument (instance_expr));
}
args.AddRange (arguments);
- if (right_side != null)
- args.Add (new Argument (right_side));
- return new DynamicIndexBinder (right_side != null, args, loc).Resolve (ec);
- }
+ var expr = new DynamicIndexBinder (args, loc);
+ if (right_side != null)
+ return expr.ResolveLValue (ec, right_side);
- Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type);
- if (ilist.Methods == null) {
- ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
- TypeManager.CSharpName (indexer_type));
- return null;
+ return expr.Resolve (ec);
}
- MethodGroupExpr mg = new IndexerMethodGroupExpr (ilist, loc);
- mg = mg.OverloadResolve (ec, ref arguments, false, loc);
- if (mg == null)
- return null;
-
- MethodInfo mi = (MethodInfo) mg;
+ var mi = (MethodSpec) mg;
PropertyInfo pi = null;
for (int i = 0; i < ilist.Methods.Count; ++i) {
- if (ilist.Methods [i] == mi) {
+ if (ilist.Methods [i].MetaInfo == mi.MetaInfo) {
pi = (PropertyInfo) ilist.Properties [i];
break;
}
if (type.IsPointer && !ec.IsUnsafe)
UnsafeError (ec, loc);
- MethodInfo accessor;
+ MethodSpec accessor = null;
if (right_side == null) {
- accessor = get = pi.GetGetMethod (true);
+ var m = pi.GetGetMethod (true);
+ if (m != null)
+ accessor = get = Import.CreateMethod (m);
} else {
- accessor = set = pi.GetSetMethod (true);
+ var m = pi.GetSetMethod (true);
+ if (m != null)
+ accessor = set = Import.CreateMethod (m);
if (accessor == null && pi.GetGetMethod (true) != null) {
ec.Report.SymbolRelatedToPreviousError (pi);
ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to",
bool must_do_cs1540_check;
if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
- if (set == null)
- set = pi.GetSetMethod (true);
- else
- get = pi.GetGetMethod (true);
+ if (set == null) {
+ var m = pi.GetSetMethod (true);
+ if (m != null)
+ set = Import.CreateMethod (m);
+ } else {
+ var m = pi.GetGetMethod (true);
+ if (m != null)
+ get = Import.CreateMethod (m);
+ }
if (set != null && get != null &&
- (set.Attributes & MethodAttributes.MemberAccessMask) != (get.Attributes & MethodAttributes.MemberAccessMask)) {
- ec.Report.SymbolRelatedToPreviousError (accessor);
+ (set.MetaInfo.Attributes & MethodAttributes.MemberAccessMask) != (get.MetaInfo.Attributes & MethodAttributes.MemberAccessMask)) {
+ ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible",
TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
} else {
}
instance_expr.CheckMarshalByRefAccess (ec);
+
+ if (must_do_cs1540_check && (instance_expr != EmptyExpression.Null) &&
+ !TypeManager.IsInstantiationOfSameGenericType (instance_expr.Type, ec.CurrentType) &&
+ !TypeManager.IsNestedChildOf (ec.CurrentType, instance_expr.Type) &&
+ !TypeManager.IsSubclassOf (instance_expr.Type, ec.CurrentType)) {
+ ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
+ Error_CannotAccessProtected (ec, loc, accessor.MetaInfo, instance_expr.Type, ec.CurrentType);
+ return null;
+ }
+
eclass = ExprClass.IndexerAccess;
return this;
}
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (get != null ? get : set, false);
+ return TypeManager.CSharpSignature (get != null ? get.MetaInfo : set.MetaInfo, false);
}
#if NET_4_0
var args = Arguments.MakeExpression (arguments, ctx).Concat (value);
return SLE.Expression.Block (
- SLE.Expression.Call (instance_expr.MakeExpression (ctx), set, args),
+ SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) set.MetaInfo, args),
value [0]);
}
+#endif
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
var args = Arguments.MakeExpression (arguments, ctx);
- return SLE.Expression.Call (instance_expr.MakeExpression (ctx), get, args);
+ return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) get.MetaInfo, args);
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
if (get != null)
- get = storey.MutateGenericMethod (get);
+ storey.MutateGenericMethod (get);
if (set != null)
- set = storey.MutateGenericMethod (set);
+ storey.MutateGenericMethod (set);
instance_expr.MutateHoistedGenericType (storey);
if (arguments != null)
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
Expression c = CommonResolve (ec);
public class EmptyExpression : Expression {
public static readonly Expression Null = new EmptyExpression ();
- public static readonly EmptyExpression OutAccess = new EmptyExpression ();
+ public class OutAccess : EmptyExpression
+ {
+ public static readonly OutAccess Instance = new OutAccess ();
+
+ public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
+ {
+ rc.Report.Error (206, right_side.Location,
+ "A property, indexer or dynamic member access may not be passed as `ref' or `out' parameter");
+
+ return null;
+ }
+ }
+
public static readonly EmptyExpression LValueMemberAccess = new EmptyExpression ();
public static readonly EmptyExpression LValueMemberOutAccess = new EmptyExpression ();
public static readonly EmptyExpression UnaryAddress = new EmptyExpression ();
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return this;
}
private EmptyExpressionStatement ()
{
- eclass = ExprClass.Value;
loc = Location.Null;
}
// Do nothing
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
+ eclass = ExprClass.Value;
type = TypeManager.object_type;
return this;
}
}
public class UserCast : Expression {
- MethodInfo method;
+ MethodSpec method;
Expression source;
- public UserCast (MethodInfo method, Expression source, Location l)
+ public UserCast (MethodSpec method, Expression source, Location l)
{
this.method = method;
this.source = source;
return CreateExpressionFactoryCall (ec, "Convert", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method);
+ ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method.MetaInfo);
if (oa != null)
AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
public override void Emit (EmitContext ec)
{
source.Emit (ec);
- ec.ig.Emit (OpCodes.Call, method);
+ ec.ig.Emit (OpCodes.Call, (MethodInfo) method.MetaInfo);
}
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (method);
+ return TypeManager.CSharpSignature (method.MetaInfo);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Convert (source.MakeExpression (ctx), type, method);
+ return SLE.Expression.Convert (source.MakeExpression (ctx), type, (MethodInfo) method.MetaInfo);
}
-#endif
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
source.MutateHoistedGenericType (storey);
- method = storey.MutateGenericMethod (method);
+ storey.MutateGenericMethod (method);
}
}
return nullable.ResolveAsTypeTerminal (ec, false);
}
- if (dim == "*" && !TypeManager.VerifyUnManaged (ltype, loc))
+ if (dim == "*" && !TypeManager.VerifyUnmanaged (ec.Compiler, ltype, loc))
return null;
if (dim.Length != 0 && dim [0] == '[') {
array.Emit (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
//
// We are born fully resolved
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
count = count.Resolve (ec);
if (count == null)
otype = texpr.Type;
- if (!TypeManager.VerifyUnManaged (otype, loc))
+ if (!TypeManager.VerifyUnmanaged (ec.Compiler, otype, loc))
return null;
type = TypeManager.GetPointerType (otype);
args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
if (source == null)
return EmptyExpressionStatement.Instance;
//
Constant c = source as Constant;
if (c != null && c.IsDefaultInitializer (type) && target.eclass == ExprClass.Variable)
- return EmptyExpressionStatement.Instance.DoResolve (ec);
+ return EmptyExpressionStatement.Instance.Resolve (ec);
return expr;
}
this.loc = argument.Location;
}
- public CollectionElementInitializer (ArrayList arguments, Location loc)
+ public CollectionElementInitializer (List<Expression> arguments, Location loc)
: base (null, new Arguments (arguments.Count))
{
foreach (Expression e in arguments)
Arguments args = new Arguments (2);
args.Add (new Argument (mg.CreateExpressionTree (ec)));
- ArrayList expr_initializers = new ArrayList (arguments.Count);
+ var expr_initializers = new ArrayInitializer (arguments.Count, loc);
foreach (Argument a in arguments)
expr_initializers.Add (a.CreateExpressionTree (ec));
target.arguments = arguments.Clone (clonectx);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (eclass != ExprClass.Invalid)
- return this;
-
base.expr = new AddMemberAccess (ec.CurrentInitializerVariable, loc);
return base.DoResolve (ec);
//
public class CollectionOrObjectInitializers : ExpressionStatement
{
- ArrayList initializers;
+ IList<Expression> initializers;
bool is_collection_initialization;
public static readonly CollectionOrObjectInitializers Empty =
- new CollectionOrObjectInitializers (new ArrayList (0), Location.Null);
+ new CollectionOrObjectInitializers (Array.AsReadOnly (new Expression [0]), Location.Null);
- public CollectionOrObjectInitializers (ArrayList initializers, Location loc)
+ public CollectionOrObjectInitializers (IList<Expression> initializers, Location loc)
{
this.initializers = initializers;
this.loc = loc;
{
CollectionOrObjectInitializers t = (CollectionOrObjectInitializers) target;
- t.initializers = new ArrayList (initializers.Count);
- foreach (Expression e in initializers)
+ t.initializers = new List<Expression> (initializers.Count);
+ foreach (var e in initializers)
t.initializers.Add (e.Clone (clonectx));
}
public override Expression CreateExpressionTree (ResolveContext ec)
{
- ArrayList expr_initializers = new ArrayList (initializers.Count);
+ var expr_initializers = new ArrayInitializer (initializers.Count, loc);
foreach (Expression e in initializers) {
Expression expr = e.CreateExpressionTree (ec);
if (expr != null)
return new ImplicitlyTypedArrayCreation ("[]", expr_initializers, loc);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (eclass != ExprClass.Invalid)
- return this;
-
- ArrayList element_names = null;
+ List<string> element_names = null;
for (int i = 0; i < initializers.Count; ++i) {
Expression initializer = (Expression) initializers [i];
ElementInitializer element_initializer = initializer as ElementInitializer;
if (i == 0) {
if (element_initializer != null) {
- element_names = new ArrayList (initializers.Count);
+ element_names = new List<string> (initializers.Count);
element_names.Add (element_initializer.Name);
} else if (initializer is CompletingExpression){
initializer.Resolve (ec);
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return this;
}
args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (eclass != ExprClass.Invalid)
- return this;
-
Expression e = base.DoResolve (ec);
if (type == null)
return null;
}
}
- public class AnonymousTypeDeclaration : Expression
+ public class NewAnonymousType : New
{
- ArrayList parameters;
+ static readonly IList<AnonymousTypeParameter> EmptyParameters = Array.AsReadOnly (new AnonymousTypeParameter[0]);
+
+ List<AnonymousTypeParameter> parameters;
readonly TypeContainer parent;
- static readonly ArrayList EmptyParameters = new ArrayList (0);
+ AnonymousTypeClass anonymous_type;
- public AnonymousTypeDeclaration (ArrayList parameters, TypeContainer parent, Location loc)
+ public NewAnonymousType (List<AnonymousTypeParameter> parameters, TypeContainer parent, Location loc)
+ : base (null, null, loc)
{
this.parameters = parameters;
this.parent = parent;
- this.loc = loc;
}
protected override void CloneTo (CloneContext clonectx, Expression target)
if (parameters == null)
return;
- AnonymousTypeDeclaration t = (AnonymousTypeDeclaration) target;
- t.parameters = new ArrayList (parameters.Count);
+ NewAnonymousType t = (NewAnonymousType) target;
+ t.parameters = new List<AnonymousTypeParameter> (parameters.Count);
foreach (AnonymousTypeParameter atp in parameters)
- t.parameters.Add (atp.Clone (clonectx));
+ t.parameters.Add ((AnonymousTypeParameter) atp.Clone (clonectx));
}
- AnonymousTypeClass CreateAnonymousType (ResolveContext ec, ArrayList parameters)
+ AnonymousTypeClass CreateAnonymousType (ResolveContext ec, IList<AnonymousTypeParameter> parameters)
{
AnonymousTypeClass type = parent.Module.Compiled.GetAnonymousType (parameters);
if (type != null)
public override Expression CreateExpressionTree (ResolveContext ec)
{
- throw new NotSupportedException ("ET");
+ if (parameters == null)
+ return base.CreateExpressionTree (ec);
+
+ var init = new ArrayInitializer (parameters.Count, loc);
+ foreach (Property p in anonymous_type.Properties)
+ init.Add (new TypeOfMethod (Import.CreateMethod (TypeBuilder.GetMethod (type, p.GetBuilder)), loc));
+
+ var ctor_args = new ArrayInitializer (Arguments.Count, loc);
+ foreach (Argument a in Arguments)
+ ctor_args.Add (a.CreateExpressionTree (ec));
+
+ Arguments args = new Arguments (3);
+ args.Add (new Argument (method.CreateExpressionTree (ec)));
+ args.Add (new Argument (new ArrayCreation (TypeManager.expression_type_expr, "[]", ctor_args, loc)));
+ args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", init, loc)));
+
+ return CreateExpressionFactoryCall (ec, "New", args);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- AnonymousTypeClass anonymous_type;
-
if (ec.HasSet (ResolveContext.Options.ConstantScope)) {
ec.Report.Error (836, loc, "Anonymous types cannot be used in this expression");
return null;
if (parameters == null) {
anonymous_type = CreateAnonymousType (ec, EmptyParameters);
- return new New (new TypeExpression (anonymous_type.TypeBuilder, loc),
- null, loc).Resolve (ec);
+ RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc);
+ return base.DoResolve (ec);
}
bool error = false;
- Arguments arguments = new Arguments (parameters.Count);
+ Arguments = new Arguments (parameters.Count);
TypeExpression [] t_args = new TypeExpression [parameters.Count];
for (int i = 0; i < parameters.Count; ++i) {
Expression e = ((AnonymousTypeParameter) parameters [i]).Resolve (ec);
continue;
}
- arguments.Add (new Argument (e));
+ Arguments.Add (new Argument (e));
t_args [i] = new TypeExpression (e.Type, e.Location);
}
if (anonymous_type == null)
return null;
- GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
- new TypeArguments (t_args), loc);
-
- return new New (te, arguments, loc).Resolve (ec);
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new InternalErrorException ("Should not be reached");
+ RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc);
+ return base.DoResolve (ec);
}
}
return Name.GetHashCode ();
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
Expression e = expr.Resolve (ec);
if (e == null)