protected override Expression DoResolve(ResolveContext rc) { if (rc.HasSet(ResolveContext.Options.LockScope)) { rc.Report.Error(1996, loc, "The `await' operator cannot be used in the body of a lock statement"); } if (rc.IsUnsafe) { rc.Report.Error(4004, loc, "The `await' operator cannot be used in an unsafe context"); } var bc = (BlockContext)rc; stmt = new AwaitStatement(expr, loc); if (!stmt.Resolve(bc)) { return(null); } if (rc.HasSet(ResolveContext.Options.FinallyScope) && rc.CurrentAnonymousMethod != null) { var ats = (AsyncTaskStorey)rc.CurrentAnonymousMethod.Storey; ats.HasAwaitInsideFinally = true; } type = stmt.ResultType; eclass = ExprClass.Variable; return(this); }
protected override Expression DoResolve(ResolveContext rc) { if (rc.HasSet(ResolveContext.Options.FinallyScope)) { rc.Report.Error(1984, loc, "The `await' operator cannot be used in the body of a finally clause"); } if (rc.HasSet(ResolveContext.Options.LockScope)) { rc.Report.Error(1996, loc, "The `await' operator cannot be used in the body of a lock statement"); } if (rc.IsUnsafe) { rc.Report.Error(4004, loc, "The `await' operator cannot be used in an unsafe context"); } var bc = (BlockContext)rc; stmt = new AwaitStatement(expr, loc); if (!stmt.Resolve(bc)) { return(null); } type = stmt.ResultType; eclass = ExprClass.Variable; return(this); }
public BlockContext(ResolveContext rc, ExplicitBlock block, TypeSpec returnType) : this(rc.MemberContext, block, returnType) { if (rc.IsUnsafe) { flags |= ResolveContext.Options.UnsafeScope; } if (rc.HasSet(ResolveContext.Options.CheckedScope)) { flags |= ResolveContext.Options.CheckedScope; } if (rc.IsInProbingMode) { flags |= ResolveContext.Options.ProbingMode; } if (rc.HasSet(ResolveContext.Options.FieldInitializerScope)) { flags |= ResolveContext.Options.FieldInitializerScope; } if (rc.HasSet(ResolveContext.Options.ExpressionTreeConversion)) { flags |= ResolveContext.Options.ExpressionTreeConversion; } if (rc.HasSet(ResolveContext.Options.BaseInitializer)) { flags |= ResolveContext.Options.BaseInitializer; } }
protected override Expression DoResolve(ResolveContext rc) { if (rc.HasSet(ResolveContext.Options.FinallyScope)) { rc.Report.Error(1984, loc, "The `await' operator cannot be used in the body of a finally clause"); } if (rc.HasSet(ResolveContext.Options.CatchScope)) { rc.Report.Error(1985, loc, "The `await' operator cannot be used in the body of a catch clause"); } if (rc.HasSet(ResolveContext.Options.LockScope)) { rc.Report.Error(1996, loc, "The `await' operator cannot be used in the body of a lock statement"); } if (rc.HasSet(ResolveContext.Options.ExpressionTreeConversion)) { rc.Report.Error(1989, loc, "An expression tree cannot contain an await operator"); return(null); } if (rc.IsUnsafe) { // TODO: New error code rc.Report.Error(-1900, loc, "The `await' operator cannot be used in an unsafe context"); } var bc = (BlockContext)rc; if (!bc.CurrentBlock.ParametersBlock.IsAsync) { // TODO: Should check for existence of await type but // what to do with it } stmt = new AwaitStatement(expr, loc); if (!stmt.Resolve(bc)) { return(null); } type = stmt.ResultType; eclass = ExprClass.Variable; return(this); }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(4); MemberAccess ns; if (ec.Module.PredefinedTypes.IsPlayScriptAotMode) { ns = new QualifiedAliasMember(QualifiedAliasMember.GlobalAlias, "PlayScript", loc); } else { ns = new MemberAccess(new MemberAccess( new QualifiedAliasMember(QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); } var flags = ec.HasSet(ResolveContext.Options.CheckedScope) ? CSharpBinderFlags.CheckedContext : 0; binder_args.Add(new Argument(new BinderFlags(flags, this))); binder_args.Add(new Argument(new MemberAccess(new MemberAccess(ns, "ExpressionType", loc), name, loc))); binder_args.Add(new Argument(new TypeOf(ec.CurrentType, loc))); binder_args.Add(new Argument(new ImplicitlyTypedArrayCreation(args.CreateDynamicBinderArguments(ec), loc))); return(new Invocation(GetBinder("UnaryOperation", loc), binder_args)); }
void ResolveConditionalAccessReceiver(ResolveContext rc) { // LAMESPEC: Not sure why this is explicitly disalloed with very odd error message if (!rc.HasSet(ResolveContext.Options.DontSetConditionalAccessReceiver) && method_group.HasConditionalAccess()) { Error_OperatorCannotBeApplied(rc, loc, "?", method_group.Type); } }
protected override Expression DoResolve(ResolveContext rc) { if (!rc.HasSet(ResolveContext.Options.DontSetConditionalAccessReceiver)) { conditionalAccessReceiver = HasConditionalAccess() || Arguments [0].Expr.HasConditionalAccess(); } return(base.DoResolve(rc)); }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(3); flags |= ec.HasSet(ResolveContext.Options.CheckedScope) ? CSharpBinderFlags.CheckedContext : 0; binder_args.Add(new Argument(new BinderFlags(flags, this))); binder_args.Add(new Argument(new TypeOf(type, loc))); binder_args.Add(new Argument(new TypeOf(ec.CurrentType, loc))); return(new Invocation(GetBinder("Convert", loc), binder_args)); }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(2); MemberAccess binder = GetBinderNamespace(loc); binder_args.Add(new Argument(new TypeOf(new TypeExpression(type, loc), loc))); binder_args.Add(new Argument(new MemberAccess(new MemberAccess(binder, "CSharpConversionKind", loc), is_explicit ? "ExplicitConversion" : "ImplicitConversion", loc))); binder_args.Add(new Argument(new BoolLiteral(ec.HasSet(ResolveContext.Options.CheckedScope), loc))); return(new New(new MemberAccess(binder, "CSharpConvertBinder", loc), binder_args, loc)); }
public BlockContext(ResolveContext rc, ExplicitBlock block, TypeSpec returnType) : this(rc.MemberContext, block, returnType) { if (rc.IsUnsafe) { flags |= ResolveContext.Options.UnsafeScope; } if (rc.HasSet(ResolveContext.Options.CheckedScope)) { flags |= ResolveContext.Options.CheckedScope; } }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(3); MemberAccess sle = new MemberAccess(new MemberAccess( new QualifiedAliasMember(QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); MemberAccess binder = GetBinderNamespace(loc); binder_args.Add(new Argument(new MemberAccess(new MemberAccess(sle, "ExpressionType", loc), name, loc))); binder_args.Add(new Argument(new BoolLiteral(ec.HasSet(ResolveContext.Options.CheckedScope), loc))); binder_args.Add(new Argument(new ImplicitlyTypedArrayCreation("[]", args.CreateDynamicBinderArguments(), loc))); return(new New(new MemberAccess(binder, "CSharpUnaryOperationBinder", loc), binder_args, loc)); }
// // Returns AnonymousMethod container if this anonymous method // expression can be implicitly converted to the delegate type `delegate_type' // public Expression Compatible (ResolveContext ec, TypeSpec type) { Expression am; if (compatibles.TryGetValue (type, out am)) return am; TypeSpec delegate_type = CompatibleChecks (ec, type); if (delegate_type == null) return null; // // At this point its the first time we know the return type that is // needed for the anonymous method. We create the method here. // var invoke_mb = Delegate.GetInvokeMethod (delegate_type); TypeSpec return_type = invoke_mb.ReturnType; // // Second: the return type of the delegate must be compatible with // the anonymous type. Instead of doing a pass to examine the block // we satisfy the rule by setting the return type on the EmitContext // to be the delegate type return type. // var body = CompatibleMethodBody (ec, null, return_type, delegate_type); if (body == null) return null; bool etree_conversion = delegate_type != type; try { if (etree_conversion) { if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { // // Nested expression tree lambda use same scope as parent // lambda, this also means no variable capturing between this // and parent scope // am = body.Compatible (ec, ec.CurrentAnonymousMethod); // // Quote nested expression tree // if (am != null) am = new Quote (am); } else { int errors = ec.Report.Errors; using (ec.Set (ResolveContext.Options.ExpressionTreeConversion)) { am = body.Compatible (ec); } // // Rewrite expressions into expression tree when targeting Expression<T> // if (am != null && errors == ec.Report.Errors) am = CreateExpressionTree (ec, delegate_type); } } else { if (Block.IsAsync) { var rt = body.ReturnType; if (rt.Kind != MemberKind.Void && rt != ec.Module.PredefinedTypes.Task.TypeSpec && !rt.IsGenericTask) { ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'", GetSignatureForError (), type.GetSignatureForError ()); } AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent, rt, loc); } am = body.Compatible (ec); } } catch (CompletionResult) { throw; } catch (Exception e) { throw new InternalErrorException (e, loc); } if (!ec.IsInProbingMode) { compatibles.Add (type, am ?? EmptyExpression.Null); } return am; }
public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (2); MemberAccess binder = GetBinderNamespace (loc); binder_args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); binder_args.Add (new Argument (new MemberAccess (new MemberAccess (binder, "CSharpConversionKind", loc), is_explicit ? "ExplicitConversion" : "ImplicitConversion", loc))); binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (ResolveContext.Options.CheckedScope), loc))); return new New (new MemberAccess (binder, "CSharpConvertBinder", loc), binder_args, loc); }
public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (3); MemberAccess sle = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); MemberAccess binder = GetBinderNamespace (loc); binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), name, loc))); binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (ResolveContext.Options.CheckedScope), loc))); binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc))); return new New (new MemberAccess (binder, "CSharpUnaryOperationBinder", loc), binder_args, loc); }
/// <summary> /// Constant expression folder for binary operations. /// /// Returns null if the expression can not be folded. /// </summary> static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper, Constant left, Constant right, Location loc) { Constant result = null; if (left is EmptyConstantCast) return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc); if (left is SideEffectConstant) { result = BinaryFold (ec, oper, ((SideEffectConstant) left).value, right, loc); if (result == null) return null; return new SideEffectConstant (result, left, loc); } if (right is EmptyConstantCast) return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc); if (right is SideEffectConstant) { result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).value, loc); if (result == null) return null; return new SideEffectConstant (result, right, loc); } TypeSpec lt = left.Type; TypeSpec rt = right.Type; bool bool_res; if (lt.BuiltinType == BuiltinTypeSpec.Type.Bool && lt == rt) { bool lv = (bool) left.GetValue (); bool rv = (bool) right.GetValue (); switch (oper) { case Binary.Operator.BitwiseAnd: case Binary.Operator.LogicalAnd: return new BoolConstant (ec.BuiltinTypes, lv && rv, left.Location); case Binary.Operator.BitwiseOr: case Binary.Operator.LogicalOr: return new BoolConstant (ec.BuiltinTypes, lv || rv, left.Location); case Binary.Operator.ExclusiveOr: return new BoolConstant (ec.BuiltinTypes, lv ^ rv, left.Location); case Binary.Operator.Equality: return new BoolConstant (ec.BuiltinTypes, lv == rv, left.Location); case Binary.Operator.Inequality: return new BoolConstant (ec.BuiltinTypes, lv != rv, left.Location); } return null; } // // During an enum evaluation, none of the rules are valid // Not sure whether it is bug in csc or in documentation // if (ec.HasSet (ResolveContext.Options.EnumScope)){ if (left is EnumConstant) left = ((EnumConstant) left).Child; if (right is EnumConstant) right = ((EnumConstant) right).Child; } else if (left is EnumConstant && rt == lt) { switch (oper){ /// /// E operator |(E x, E y); /// E operator &(E x, E y); /// E operator ^(E x, E y); /// case Binary.Operator.BitwiseOr: case Binary.Operator.BitwiseAnd: case Binary.Operator.ExclusiveOr: result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc); if (result != null) result = result.TryReduce (ec, lt); return result; /// /// U operator -(E x, E y); /// case Binary.Operator.Subtraction: result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc); if (result != null) result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt)); return result; /// /// bool operator ==(E x, E y); /// bool operator !=(E x, E y); /// bool operator <(E x, E y); /// bool operator >(E x, E y); /// bool operator <=(E x, E y); /// bool operator >=(E x, E y); /// case Binary.Operator.Equality: case Binary.Operator.Inequality: case Binary.Operator.LessThan: case Binary.Operator.GreaterThan: case Binary.Operator.LessThanOrEqual: case Binary.Operator.GreaterThanOrEqual: return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc); } return null; } switch (oper){ case Binary.Operator.BitwiseOr: // // bool? operator &(bool? x, bool? y); // if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) || (rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) { var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); // false | null => null // null | false => null if ((right is NullLiteral && left.IsDefaultValue) || (left is NullLiteral && right.IsDefaultValue)) return Nullable.LiftedNull.CreateFromExpression (ec, b); // true | null => true // null | true => true return ReducedExpression.Create (new BoolConstant (ec.BuiltinTypes, true, loc), b); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; if (left is IntConstant){ int res = ((IntConstant) left).Value | ((IntConstant) right).Value; return new IntConstant (ec.BuiltinTypes, res, left.Location); } if (left is UIntConstant){ uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value; return new UIntConstant (ec.BuiltinTypes, res, left.Location); } if (left is LongConstant){ long res = ((LongConstant)left).Value | ((LongConstant)right).Value; return new LongConstant (ec.BuiltinTypes, res, left.Location); } if (left is ULongConstant){ ulong res = ((ULongConstant)left).Value | ((ULongConstant)right).Value; return new ULongConstant (ec.BuiltinTypes, res, left.Location); } break; case Binary.Operator.BitwiseAnd: // // bool? operator &(bool? x, bool? y); // if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) || (rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) { var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); // false & null => false // null & false => false if ((right is NullLiteral && left.IsDefaultValue) || (left is NullLiteral && right.IsDefaultValue)) return ReducedExpression.Create (new BoolConstant (ec.BuiltinTypes, false, loc), b); // true & null => null // null & true => null return Nullable.LiftedNull.CreateFromExpression (ec, b); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; /// /// int operator &(int x, int y); /// uint operator &(uint x, uint y); /// long operator &(long x, long y); /// ulong operator &(ulong x, ulong y); /// if (left is IntConstant){ int res = ((IntConstant) left).Value & ((IntConstant) right).Value; return new IntConstant (ec.BuiltinTypes, res, left.Location); } if (left is UIntConstant){ uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value; return new UIntConstant (ec.BuiltinTypes, res, left.Location); } if (left is LongConstant){ long res = ((LongConstant)left).Value & ((LongConstant)right).Value; return new LongConstant (ec.BuiltinTypes, res, left.Location); } if (left is ULongConstant){ ulong res = ((ULongConstant)left).Value & ((ULongConstant)right).Value; return new ULongConstant (ec.BuiltinTypes, res, left.Location); } break; case Binary.Operator.ExclusiveOr: if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; if (left is IntConstant){ int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value; return new IntConstant (ec.BuiltinTypes, res, left.Location); } if (left is UIntConstant){ uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value; return new UIntConstant (ec.BuiltinTypes, res, left.Location); } if (left is LongConstant){ long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value; return new LongConstant (ec.BuiltinTypes, res, left.Location); } if (left is ULongConstant){ ulong res = ((ULongConstant)left).Value ^ ((ULongConstant)right).Value; return new ULongConstant (ec.BuiltinTypes, res, left.Location); } break; case Binary.Operator.Addition: if (lt == InternalType.NullLiteral) return right; if (rt == InternalType.NullLiteral) return left; // // If both sides are strings, then concatenate, if // one is a string, and the other is not, then defer // to runtime concatenation // if (lt.BuiltinType == BuiltinTypeSpec.Type.String || rt.BuiltinType == BuiltinTypeSpec.Type.String){ if (lt == rt) return new StringConstant (ec.BuiltinTypes, (string)left.GetValue () + (string)right.GetValue (), left.Location); return null; } // // handle "E operator + (E x, U y)" // handle "E operator + (Y y, E x)" // EnumConstant lc = left as EnumConstant; EnumConstant rc = right as EnumConstant; if (lc != null || rc != null){ if (lc == null) { lc = rc; lt = lc.Type; right = left; } // U has to be implicitly convetible to E.base right = right.ConvertImplicitly (lc.Child.Type); if (right == null) return null; result = BinaryFold (ec, oper, lc.Child, right, loc); if (result == null) return null; result = result.TryReduce (ec, lt); if (result == null) return null; return new EnumConstant (result, lt); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; try { if (left is DoubleConstant){ double res; if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value + ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value + ((DoubleConstant) right).Value); return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value + ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value + ((FloatConstant) right).Value); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value + ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value + ((ULongConstant) right).Value); result = new ULongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value + ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value + ((LongConstant) right).Value); result = new LongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value + ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value + ((UIntConstant) right).Value); result = new UIntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value + ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value + ((IntConstant) right).Value); result = new IntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is DecimalConstant) { decimal res; if (ec.ConstantCheckState) res = checked (((DecimalConstant) left).Value + ((DecimalConstant) right).Value); else res = unchecked (((DecimalConstant) left).Value + ((DecimalConstant) right).Value); result = new DecimalConstant (ec.BuiltinTypes, res, left.Location); } } catch (OverflowException){ Error_CompileTimeOverflow (ec, loc); } return result; case Binary.Operator.Subtraction: // // handle "E operator - (E x, U y)" // handle "E operator - (Y y, E x)" // lc = left as EnumConstant; rc = right as EnumConstant; if (lc != null || rc != null){ if (lc == null) { lc = rc; lt = lc.Type; right = left; } // U has to be implicitly convetible to E.base right = right.ConvertImplicitly (lc.Child.Type); if (right == null) return null; result = BinaryFold (ec, oper, lc.Child, right, loc); if (result == null) return null; result = result.TryReduce (ec, lt); if (result == null) return null; return new EnumConstant (result, lt); } if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; try { if (left is DoubleConstant){ double res; if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value - ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value - ((DoubleConstant) right).Value); result = new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value - ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value - ((FloatConstant) right).Value); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value - ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value - ((ULongConstant) right).Value); result = new ULongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value - ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value - ((LongConstant) right).Value); result = new LongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value - ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value - ((UIntConstant) right).Value); result = new UIntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value - ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value - ((IntConstant) right).Value); result = new IntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is DecimalConstant) { decimal res; if (ec.ConstantCheckState) res = checked (((DecimalConstant) left).Value - ((DecimalConstant) right).Value); else res = unchecked (((DecimalConstant) left).Value - ((DecimalConstant) right).Value); return new DecimalConstant (ec.BuiltinTypes, res, left.Location); } else { throw new Exception ( "Unexepected subtraction input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (ec, loc); } return result; case Binary.Operator.Multiply: if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; try { if (left is DoubleConstant){ double res; if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value * ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value * ((DoubleConstant) right).Value); return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value * ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value * ((FloatConstant) right).Value); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value * ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value * ((ULongConstant) right).Value); return new ULongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value * ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value * ((LongConstant) right).Value); return new LongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value * ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value * ((UIntConstant) right).Value); return new UIntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value * ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value * ((IntConstant) right).Value); return new IntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is DecimalConstant) { decimal res; if (ec.ConstantCheckState) res = checked (((DecimalConstant) left).Value * ((DecimalConstant) right).Value); else res = unchecked (((DecimalConstant) left).Value * ((DecimalConstant) right).Value); return new DecimalConstant (ec.BuiltinTypes, res, left.Location); } else { throw new Exception ( "Unexepected multiply input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (ec, loc); } break; case Binary.Operator.Division: if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; try { if (left is DoubleConstant){ double res; if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value / ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value / ((DoubleConstant) right).Value); return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value / ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value / ((FloatConstant) right).Value); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value / ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value / ((ULongConstant) right).Value); return new ULongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value / ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value / ((LongConstant) right).Value); return new LongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value / ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value / ((UIntConstant) right).Value); return new UIntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value / ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value / ((IntConstant) right).Value); return new IntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is DecimalConstant) { decimal res; if (ec.ConstantCheckState) res = checked (((DecimalConstant) left).Value / ((DecimalConstant) right).Value); else res = unchecked (((DecimalConstant) left).Value / ((DecimalConstant) right).Value); return new DecimalConstant (ec.BuiltinTypes, res, left.Location); } else { throw new Exception ( "Unexepected division input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (ec, loc); } catch (DivideByZeroException) { ec.Report.Error (20, loc, "Division by constant zero"); } break; case Binary.Operator.Modulus: if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; try { if (left is DoubleConstant){ double res; if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value % ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value % ((DoubleConstant) right).Value); return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value % ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value % ((FloatConstant) right).Value); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value % ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value % ((ULongConstant) right).Value); return new ULongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value % ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value % ((LongConstant) right).Value); return new LongConstant (ec.BuiltinTypes, res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value % ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value % ((UIntConstant) right).Value); return new UIntConstant (ec.BuiltinTypes, res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value % ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value % ((IntConstant) right).Value); return new IntConstant (ec.BuiltinTypes, res, left.Location); } else { throw new Exception ( "Unexepected modulus input: " + left); } } catch (DivideByZeroException){ ec.Report.Error (20, loc, "Division by constant zero"); } catch (OverflowException){ Error_CompileTimeOverflow (ec, loc); } break; // // There is no overflow checking on left shift // case Binary.Operator.LeftShift: if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (ic == null){ Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); return null; } int lshift_val = ic.Value; switch (left.Type.BuiltinType) { case BuiltinTypeSpec.Type.ULong: return new ULongConstant (ec.BuiltinTypes, ((ULongConstant) left).Value << lshift_val, left.Location); case BuiltinTypeSpec.Type.Long: return new LongConstant (ec.BuiltinTypes, ((LongConstant) left).Value << lshift_val, left.Location); case BuiltinTypeSpec.Type.UInt: return new UIntConstant (ec.BuiltinTypes, ((UIntConstant) left).Value << lshift_val, left.Location); } // null << value => null if (left is NullLiteral) return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); left = left.ConvertImplicitly (ec.BuiltinTypes.Int); if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value << lshift_val, left.Location); Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); break; // // There is no overflow checking on right shift // case Binary.Operator.RightShift: if (left is NullLiteral && right is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (sic == null){ Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); ; return null; } int rshift_val = sic.Value; switch (left.Type.BuiltinType) { case BuiltinTypeSpec.Type.ULong: return new ULongConstant (ec.BuiltinTypes, ((ULongConstant) left).Value >> rshift_val, left.Location); case BuiltinTypeSpec.Type.Long: return new LongConstant (ec.BuiltinTypes, ((LongConstant) left).Value >> rshift_val, left.Location); case BuiltinTypeSpec.Type.UInt: return new UIntConstant (ec.BuiltinTypes, ((UIntConstant) left).Value >> rshift_val, left.Location); } // null >> value => null if (left is NullLiteral) return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); left = left.ConvertImplicitly (ec.BuiltinTypes.Int); if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value >> rshift_val, left.Location); Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); break; case Binary.Operator.Equality: if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) || (left is Nullable.LiftedNull && right.IsNull) || (right is Nullable.LiftedNull && left.IsNull)) { if (left.IsNull || right.IsNull) { return ReducedExpression.Create ( new BoolConstant (ec.BuiltinTypes, left.IsNull == right.IsNull, left.Location), new Binary (oper, left, right)); } if (left is StringConstant && right is StringConstant) return new BoolConstant (ec.BuiltinTypes, ((StringConstant) left).Value == ((StringConstant) right).Value, left.Location); return null; } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value == ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value == ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value == ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value == ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value == ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value == ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); case Binary.Operator.Inequality: if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) || (left is Nullable.LiftedNull && right.IsNull) || (right is Nullable.LiftedNull && left.IsNull)) { if (left.IsNull || right.IsNull) { return ReducedExpression.Create ( new BoolConstant (ec.BuiltinTypes, left.IsNull != right.IsNull, left.Location), new Binary (oper, left, right)); } if (left is StringConstant && right is StringConstant) return new BoolConstant (ec.BuiltinTypes, ((StringConstant) left).Value != ((StringConstant) right).Value, left.Location); return null; } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value != ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value != ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value != ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value != ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value != ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value != ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); case Binary.Operator.LessThan: if (right is NullLiteral) { if (left is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (left is Nullable.LiftedNull) { return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); } } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value < ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value < ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value < ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value < ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value < ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value < ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); case Binary.Operator.GreaterThan: if (right is NullLiteral) { if (left is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (left is Nullable.LiftedNull) { return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); } } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value > ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value > ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value > ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value > ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value > ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value > ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); case Binary.Operator.GreaterThanOrEqual: if (right is NullLiteral) { if (left is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (left is Nullable.LiftedNull) { return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); } } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value >= ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value >= ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value >= ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value >= ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value >= ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value >= ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); case Binary.Operator.LessThanOrEqual: if (right is NullLiteral) { if (left is NullLiteral) { var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); lifted_int.ResolveAsType (ec); return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec); } if (left is Nullable.LiftedNull) { return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); } } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) return null; bool_res = false; if (left is DoubleConstant) bool_res = ((DoubleConstant) left).Value <= ((DoubleConstant) right).Value; else if (left is FloatConstant) bool_res = ((FloatConstant) left).Value <= ((FloatConstant) right).Value; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value <= ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value <= ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value <= ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value <= ((IntConstant) right).Value; else return null; return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); } return null; }
protected override Expression DoResolve(ResolveContext ec) { right = right.Resolve(ec); if (right == null) { return(null); } MemberAccess ma = target as MemberAccess; using (ec.Set(ResolveContext.Options.CompoundAssignmentScope)) { target = target.Resolve(ec); } if (target == null) { return(null); } if (target is MethodGroupExpr) { ec.Report.Error(1656, loc, "Cannot assign to `{0}' because it is a `{1}'", ((MethodGroupExpr)target).Name, target.ExprClassName); return(null); } var event_expr = target as EventExpr; if (event_expr != null) { source = Convert.ImplicitConversionRequired(ec, right, target.Type, loc); if (source == null) { return(null); } Expression rside; if (op == Binary.Operator.Addition) { rside = EmptyExpression.EventAddition; } else if (op == Binary.Operator.Subtraction) { rside = EmptyExpression.EventSubtraction; } else { rside = null; } target = target.ResolveLValue(ec, rside); if (target == null) { return(null); } eclass = ExprClass.Value; type = event_expr.Operator.ReturnType; return(this); } // // Only now we can decouple the original source/target // into a tree, to guarantee that we do not have side // effects. // if (left == null) { left = new TargetExpression(target); } source = new Binary(op, left, right, true, loc); if (target is DynamicMemberAssignable) { Arguments targs = ((DynamicMemberAssignable)target).Arguments; source = source.Resolve(ec); Arguments args = new Arguments(targs.Count + 1); args.AddRange(targs); args.Add(new Argument(source)); var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment; // // Compound assignment does target conversion using additional method // call, set checked context as the binary operation can overflow // if (ec.HasSet(ResolveContext.Options.CheckedScope)) { binder_flags |= CSharpBinderFlags.CheckedContext; } if (target is DynamicMemberBinder) { source = new DynamicMemberBinder(ma.Name, binder_flags, args, loc).Resolve(ec); // Handles possible event addition/subtraction if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) { args = new Arguments(targs.Count + 1); args.AddRange(targs); args.Add(new Argument(right)); string method_prefix = op == Binary.Operator.Addition ? Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix; var invoke = DynamicInvocation.CreateSpecialNameInvoke( new MemberAccess(right, method_prefix + ma.Name, loc), args, loc).Resolve(ec); args = new Arguments(targs.Count); args.AddRange(targs); source = new DynamicEventCompoundAssign(ma.Name, args, (ExpressionStatement)source, (ExpressionStatement)invoke, loc).Resolve(ec); } } else { source = new DynamicIndexBinder(binder_flags, args, loc).Resolve(ec); } return(source); } return(base.DoResolve(ec)); }
protected override Expression DoResolve (ResolveContext rc) { if (!rc.HasSet (ResolveContext.Options.DontSetConditionalAccessReceiver)) conditionalAccessReceiver = HasConditionalAccess () || Arguments [0].Expr.HasConditionalAccess (); return base.DoResolve (rc); }
public override Expression DoResolveLValue(ResolveContext ec, Expression right_side) { IVariableReference var = InstanceExpression as IVariableReference; if (var != null && var.VariableInfo != null) var.VariableInfo.SetFieldAssigned (ec, Name); bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.DeclaringType); bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess; Expression e = DoResolve (ec, lvalue_instance, out_access); if (e == null) return null; spec.MemberDefinition.SetIsAssigned (); if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) && (spec.Modifiers & Modifiers.VOLATILE) != 0) { ec.Report.Warning (420, 1, loc, "`{0}': A volatile field references will not be treated as volatile", spec.GetSignatureForError ()); } if (spec.IsReadOnly) { // InitOnly fields can only be assigned in constructors or initializers if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope)) return Report_AssignToReadonly (ec, right_side); if (ec.HasSet (ResolveContext.Options.ConstructorScope)) { // InitOnly fields cannot be assigned-to in a different constructor from their declaring type if (!TypeManager.IsEqual (ec.CurrentMemberDefinition.Parent.Definition, DeclaringType.GetDefinition ())) return Report_AssignToReadonly (ec, right_side); // static InitOnly fields cannot be assigned-to in an instance constructor if (IsStatic && !ec.IsStatic) return Report_AssignToReadonly (ec, right_side); // instance constructors can't modify InitOnly fields of other instances of the same type if (!IsStatic && !(InstanceExpression is This)) return Report_AssignToReadonly (ec, right_side); } } if (right_side == EmptyExpression.OutAccess.Instance && !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) { ec.Report.SymbolRelatedToPreviousError (DeclaringType); ec.Report.Warning (197, 1, loc, "Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class", GetSignatureForError ()); } eclass = ExprClass.Variable; return this; }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (4); MemberAccess sle = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); var flags = ec.HasSet (ResolveContext.Options.CheckedScope) ? CSharpBinderFlags.CheckedContext : 0; binder_args.Add (new Argument (new BinderFlags (flags, this))); binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), name, 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 (GetBinder ("UnaryOperation", loc), binder_args); }
protected override Expression DoResolve (ResolveContext ec) { if (ec.HasSet (ResolveContext.Options.ConstantScope)) { ec.Report.Error (1706, loc, "Anonymous methods and lambda expressions cannot be used in the current context"); return null; } // // Set class type, set type // eclass = ExprClass.Value; // // This hack means `The type is not accessible // anywhere', we depend on special conversion // rules. // type = InternalType.AnonymousMethod; if (!DoResolveParameters (ec)) return null; return this; }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; ResolveContext.Options flags = 0; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } if (ec.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= ResolveContext.Options.ExpressionTreeConversion; aec.Set (flags); var errors = ec.Report.Errors; bool res = Block.Resolve (ec.CurrentBranching, aec, null); if (aec.HasReturnLabel) return_label = aec.ReturnLabel; if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }
public override Expression DoResolve (ResolveContext ec) { 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); RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc); return base.DoResolve (ec); } bool error = false; 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); if (e == null) { error = true; continue; } Arguments.Add (new Argument (e)); t_args [i] = new TypeExpression (e.Type, e.Location); } if (error) return null; anonymous_type = CreateAnonymousType (ec, parameters); if (anonymous_type == null) return null; RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc); return base.DoResolve (ec); }
public override Expression CreateExpressionTree(ResolveContext ec) { Arguments args = new Arguments (2); args.Add (new Argument (child.CreateExpressionTree (ec))); args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); if (type.IsPointer || child.Type.IsPointer) Error_PointerInsideExpressionTree (ec); return CreateExpressionFactoryCall (ec, ec.HasSet (ResolveContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args); }
public static void Error_ObjectRefRequired(ResolveContext ec, Location l, string name) { if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) ec.Report.Error (236, l, "A field initializer cannot reference the nonstatic field, method, or property `{0}'", name); else ec.Report.Error (120, l, "An object reference is required to access non-static member `{0}'", name); }
Expression DoResolve(ResolveContext ec, bool lvalue_instance, bool out_access) { if (!IsStatic){ if (InstanceExpression == null){ // // This can happen when referencing an instance field using // a fully qualified type expression: TypeName.InstanceField = xxx // SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ()); return null; } // Resolve the field's instance expression while flow analysis is turned // off: when accessing a field "a.b", we must check whether the field // "a.b" is initialized, not whether the whole struct "a" is initialized. if (lvalue_instance) { using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { Expression right_side = out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess; if (InstanceExpression != EmptyExpression.Null) InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side); } } else { if (InstanceExpression != EmptyExpression.Null) { using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue); } } } if (InstanceExpression == null) return null; using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) { InstanceExpression.CheckMarshalByRefAccess (ec); } } if (!ec.IsObsolete) { ObsoleteAttribute oa = spec.GetAttributeObsolete (); if (oa != null) AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec), loc, ec.Report); } var fb = spec as FixedFieldSpec; IVariableReference var = InstanceExpression as IVariableReference; if (fb != null) { IFixedExpression fe = InstanceExpression as IFixedExpression; if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) { ec.Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement"); } if (InstanceExpression.eclass != ExprClass.Variable) { ec.Report.SymbolRelatedToPreviousError (spec); ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields", TypeManager.GetFullNameSignature (spec)); } else if (var != null && var.IsHoisted) { AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc); } return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec); } eclass = ExprClass.Variable; // If the instance expression is a local variable or parameter. if (var == null || var.VariableInfo == null) return this; VariableInfo vi = var.VariableInfo; if (!vi.IsFieldAssigned (ec, Name, loc)) return null; variable_info = vi.GetSubStruct (Name); return this; }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; ResolveContext.Options flags = 0; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } if (ec.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= ResolveContext.Options.ExpressionTreeConversion; aec.Set (flags); var errors = ec.Report.Errors; bool res = Block.Resolve (ec.CurrentBranching, aec, null); if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; // // If e is synchronous the inferred return type is T // If e is asynchronous the inferred return type is Task<T> // if (block.IsAsync && ReturnType != null) { ReturnType = ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); } } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }
protected override Expression DoResolve (ResolveContext ec) { constructor_method = Delegate.GetConstructor (type); var invoke_method = Delegate.GetInvokeMethod (type); if (!ec.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) { if (method_group.HasConditionalAccess ()) { conditional_access_receiver = true; ec.Set (ResolveContext.Options.ConditionalAccessReceiver); } } Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (conditional_access_receiver) ec.With (ResolveContext.Options.ConditionalAccessReceiver, false); if (method_group == null) return null; var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError ()); return null; } if (!AllowSpecialMethodsInvocation) Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType (e_type)) { ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError (), e_type.GetSignatureForError ()); } } TypeSpec rt = method_group.BestCandidateReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) rt = ec.BuiltinTypes.Object; if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc); Error_ConversionFailed (ec, delegate_method, ret_expr); } if (method_group.IsConditionallyExcluded) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError ()); } else { ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type))) method_group.InstanceExpression = new BoxedCast (expr, ec.BuiltinTypes.Object); eclass = ExprClass.Value; return this; }
protected override Expression DoResolve (ResolveContext rc) { if (rc.HasSet (ResolveContext.Options.ConstantScope)) { rc.Report.Error (1706, loc, "Anonymous methods and lambda expressions cannot be used in the current context"); return null; } // // Update top-level block generated duting parsing with actual top-level block // if (rc.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.BaseInitializer) && rc.CurrentMemberDefinition.Parent.PartialContainer.PrimaryConstructorParameters != null) { var tb = rc.ConstructorBlock.ParametersBlock.TopBlock; if (Block.TopBlock != tb) { Block b = Block; while (b.Parent != Block.TopBlock && b != Block.TopBlock) b = b.Parent; b.Parent = tb; tb.IncludeBlock (Block, Block.TopBlock); b.ParametersBlock.TopBlock = tb; } } eclass = ExprClass.Value; // // This hack means `The type is not accessible // anywhere', we depend on special conversion // rules. // type = InternalType.AnonymousMethod; if (!DoResolveParameters (rc)) return null; return this; }
public override MemberExpr ResolveMemberAccess(ResolveContext ec, Expression left, Location loc, SimpleName original) { // // If the event is local to this class, we transform ourselves into a FieldExpr // if (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) { // TODO: Breaks dynamic binder as currect context fields are imported and not compiled EventField mi = spec.MemberDefinition as EventField; if (mi != null && mi.HasBackingField) { mi.SetIsUsed (); if (!ec.IsObsolete) mi.CheckObsoleteness (loc); if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) Error_AssignmentEventOnly (ec); FieldExpr ml = new FieldExpr (mi.BackingField, loc); InstanceExpression = null; return ml.ResolveMemberAccess (ec, left, loc, original); } } if (left is This && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) Error_AssignmentEventOnly (ec); return base.ResolveMemberAccess (ec, left, loc, original); }
public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (4); MemberAccess ns; if (ec.Module.PredefinedTypes.IsPlayScriptAotMode) { ns = new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "PlayScript", loc); } else { ns = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); } var flags = ec.HasSet (ResolveContext.Options.CheckedScope) ? CSharpBinderFlags.CheckedContext : 0; binder_args.Add (new Argument (new BinderFlags (flags, this))); binder_args.Add (new Argument (new MemberAccess (new MemberAccess (ns, "ExpressionType", loc), name, loc))); binder_args.Add (new Argument (new TypeOf (ec.CurrentType, loc))); binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation (args.CreateDynamicBinderArguments (ec), loc))); return new Invocation (GetBinder ("UnaryOperation", loc), binder_args); }
protected override Expression DoResolve(ResolveContext ec) { eclass = ExprClass.EventAccess; bool must_do_cs1540_check; if (!(IsMemberAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) && IsMemberAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) { ec.Report.SymbolRelatedToPreviousError (spec); ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec), ec.Report); return null; } if (!InstanceResolve (ec, must_do_cs1540_check)) return null; if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) { Error_CannotAssign (ec); return null; } if (!ec.IsObsolete) { var oa = spec.GetAttributeObsolete (); if (oa != null) AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report); } spec.MemberDefinition.SetIsUsed (); type = spec.MemberType; return this; }
public BlockContext (ResolveContext rc, ExplicitBlock block, TypeSpec returnType) : this (rc.MemberContext, block, returnType) { if (rc.IsUnsafe) flags |= ResolveContext.Options.UnsafeScope; if (rc.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; }
public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (4); MemberAccess ns; if (ec.Module.PredefinedTypes.IsPlayScriptAotMode) { ns = new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "PlayScript", loc); } else { ns = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc); } CSharpBinderFlags flags = 0; if (ec.HasSet (ResolveContext.Options.CheckedScope)) flags = CSharpBinderFlags.CheckedContext; if ((oper & Binary.Operator.LogicalMask) != 0) flags |= CSharpBinderFlags.BinaryOperationLogical; binder_args.Add (new Argument (new EnumConstant (new IntLiteral (ec.BuiltinTypes, (int) flags, loc), ec.Module.PredefinedTypes.GetBinderFlags(ec).Resolve ()))); binder_args.Add (new Argument (new MemberAccess (new MemberAccess (ns, "ExpressionType", loc), this.name, loc))); binder_args.Add (new Argument (new TypeOf (ec.CurrentType, loc))); binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation (args.CreateDynamicBinderArguments (ec), loc))); return new Invocation (new MemberAccess (new TypeExpression (ec.Module.PredefinedTypes.GetBinder(ec).TypeSpec, loc), "BinaryOperation", loc), binder_args); }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } var bc = ec as BlockContext; if (bc != null) { aec.AssignmentInfoOffset = bc.AssignmentInfoOffset; aec.EnclosingLoop = bc.EnclosingLoop; aec.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch; aec.Switch = bc.Switch; } var errors = ec.Report.Errors; bool res = Block.Resolve (aec); if (res && errors == ec.Report.Errors) { MarkReachable (new Reachability ()); if (!CheckReachableExit (ec.Report)) { return null; } if (bc != null) bc.AssignmentInfoOffset = aec.AssignmentInfoOffset; } if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; // // If e is synchronous the inferred return type is T // If e is asynchronous and the body of F is either an expression classified as nothing // or a statement block where no return statements have expressions, the inferred return type is Task // If e is async and has an inferred result type T, the inferred return type is Task<T> // if (block.IsAsync && ReturnType != null) { ReturnType = ReturnType.Kind == MemberKind.Void ? ec.Module.PredefinedTypes.Task.TypeSpec : ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); } } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }
protected override Expression DoResolve (ResolveContext ec) { if (ec.HasSet (ResolveContext.Options.ConstantScope)) { ec.Report.Error (1706, loc, "Anonymous methods and lambda expressions cannot be used in the current context"); return null; } // // Set class type, set type // eclass = ExprClass.Value; // // This hack means `The type is not accessible // anywhere', we depend on special conversion // rules. // type = InternalType.AnonymousMethod; if (!DoResolveParameters (ec)) return null; #if !STATIC // FIXME: The emitted code isn't very careful about reachability // so, ensure we have a 'ret' at the end BlockContext bc = ec as BlockContext; if (bc != null && bc.CurrentBranching != null && bc.CurrentBranching.CurrentUsageVector.IsUnreachable) bc.NeedReturnLabel (); #endif return this; }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments (3); flags |= ec.HasSet (ResolveContext.Options.CheckedScope) ? CSharpBinderFlags.CheckedContext : 0; binder_args.Add (new Argument (new BinderFlags (flags, this))); binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc))); binder_args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); return new Invocation (GetBinder ("Convert", loc), binder_args); }
public bool Compatible (ResolveContext ec) { // TODO: Implement clone BlockContext aec = new BlockContext (ec.MemberContext, Block, ReturnType); aec.CurrentAnonymousMethod = this; IDisposable aec_dispose = null; ResolveContext.Options flags = 0; if (ec.HasSet (ResolveContext.Options.InferReturnType)) { flags |= ResolveContext.Options.InferReturnType; aec.ReturnTypeInference = new TypeInferenceContext (); } if (ec.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (ec.IsUnsafe) flags |= ResolveContext.Options.UnsafeScope; if (ec.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; // HACK: Flag with 0 cannot be set if (flags != 0) aec_dispose = aec.Set (flags); bool res = Block.Resolve (ec.CurrentBranching, aec, Block.Parameters, null); if (aec.HasReturnLabel) return_label = aec.ReturnLabel; if (ec.HasSet (ResolveContext.Options.InferReturnType)) { aec.ReturnTypeInference.FixAllTypes (ec); ReturnType = aec.ReturnTypeInference.InferredTypeArguments [0]; } if (aec_dispose != null) { aec_dispose.Dispose (); } return res; }
protected override Expression DoResolve (ResolveContext ec) { right = right.Resolve (ec); if (right == null) return null; MemberAccess ma = target as MemberAccess; using (ec.Set (ResolveContext.Options.CompoundAssignmentScope)) { target = target.Resolve (ec); } if (target == null) return null; if (target is MethodGroupExpr){ ec.Report.Error (1656, loc, "Cannot assign to `{0}' because it is a `{1}'", ((MethodGroupExpr)target).Name, target.ExprClassName); return null; } var event_expr = target as EventExpr; if (event_expr != null) { source = Convert.ImplicitConversionRequired (ec, right, target.Type, loc); if (source == null) return null; Expression rside; if (op == Binary.Operator.Addition) rside = EmptyExpression.EventAddition; else if (op == Binary.Operator.Subtraction) rside = EmptyExpression.EventSubtraction; else rside = null; target = target.ResolveLValue (ec, rside); if (target == null) return null; eclass = ExprClass.Value; type = event_expr.Operator.ReturnType; return this; } // // Only now we can decouple the original source/target // into a tree, to guarantee that we do not have side // effects. // if (left == null) left = new TargetExpression (target); source = new Binary (op, left, right, true); if (target is DynamicMemberAssignable) { Arguments targs = ((DynamicMemberAssignable) target).Arguments; source = source.Resolve (ec); Arguments args = new Arguments (targs.Count + 1); args.AddRange (targs); args.Add (new Argument (source)); var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment; // // Compound assignment does target conversion using additional method // call, set checked context as the binary operation can overflow // if (ec.HasSet (ResolveContext.Options.CheckedScope)) binder_flags |= CSharpBinderFlags.CheckedContext; if (target is DynamicMemberBinder) { source = new DynamicMemberBinder (ma.Name, binder_flags, args, loc).Resolve (ec); // Handles possible event addition/subtraction if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) { args = new Arguments (targs.Count + 1); args.AddRange (targs); args.Add (new Argument (right)); string method_prefix = op == Binary.Operator.Addition ? Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix; var invoke = DynamicInvocation.CreateSpecialNameInvoke ( new MemberAccess (right, method_prefix + ma.Name, loc), args, loc).Resolve (ec); args = new Arguments (targs.Count); args.AddRange (targs); source = new DynamicEventCompoundAssign (ma.Name, args, (ExpressionStatement) source, (ExpressionStatement) invoke, loc).Resolve (ec); } } else { source = new DynamicIndexBinder (binder_flags, args, loc).Resolve (ec); } return source; } return base.DoResolve (ec); }
protected override Expression DoResolve(ResolveContext ec) { constructor_method = Delegate.GetConstructor(type); var invoke_method = Delegate.GetInvokeMethod(type); if (!ec.HasSet(ResolveContext.Options.ConditionalAccessReceiver)) { if (method_group.HasConditionalAccess()) { conditional_access_receiver = true; ec.Set(ResolveContext.Options.ConditionalAccessReceiver); } } Arguments arguments = CreateDelegateMethodArguments(ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve(ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (conditional_access_receiver) { ec.With(ResolveContext.Options.ConditionalAccessReceiver, false); } if (method_group == null) { return(null); } var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error(1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError()); return(null); } if (!AllowSpecialMethodsInvocation) { Invocation.IsSpecialMethodInvocation(ec, delegate_method, loc); } ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType(e_type)) { ec.Report.Error(1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError(), e_type.GetSignatureForError()); } } TypeSpec rt = method_group.BestCandidateReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { rt = ec.BuiltinTypes.Object; } if (!Delegate.IsTypeCovariant(ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression(delegate_method.ReturnType, loc); Error_ConversionFailed(ec, delegate_method, ret_expr); } if (method_group.IsConditionallyExcluded) { ec.Report.SymbolRelatedToPreviousError(delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error(762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError()); } else { ec.Report.Error(1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature(delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType(expr.Type))) { method_group.InstanceExpression = new BoxedCast(expr, ec.BuiltinTypes.Object); } eclass = ExprClass.Value; return(this); }
// // Returns AnonymousMethod container if this anonymous method // expression can be implicitly converted to the delegate type `delegate_type' // public Expression Compatible (ResolveContext ec, TypeSpec type) { Expression am; if (compatibles.TryGetValue (type, out am)) return am; TypeSpec delegate_type = CompatibleChecks (ec, type); if (delegate_type == null) return null; // // At this point its the first time we know the return type that is // needed for the anonymous method. We create the method here. // var invoke_mb = Delegate.GetInvokeMethod (delegate_type); TypeSpec return_type = invoke_mb.ReturnType; // // Second: the return type of the delegate must be compatible with // the anonymous type. Instead of doing a pass to examine the block // we satisfy the rule by setting the return type on the EmitContext // to be the delegate type return type. // var body = CompatibleMethodBody (ec, null, return_type, delegate_type); if (body == null) return null; bool etree_conversion = delegate_type != type; try { if (etree_conversion) { if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { // // Nested expression tree lambda use same scope as parent // lambda, this also means no variable capturing between this // and parent scope // am = body.Compatible (ec, ec.CurrentAnonymousMethod); // // Quote nested expression tree // if (am != null) am = new Quote (am); } else { int errors = ec.Report.Errors; if (Block.IsAsync) { ec.Report.Error (1989, loc, "Async lambda expressions cannot be converted to expression trees"); } using (ec.Set (ResolveContext.Options.ExpressionTreeConversion)) { am = body.Compatible (ec); } // // Rewrite expressions into expression tree when targeting Expression<T> // if (am != null && errors == ec.Report.Errors) am = CreateExpressionTree (ec, delegate_type); } } else { am = body.Compatible (ec); } } catch (CompletionResult) { throw; } catch (FatalException) { throw; } catch (Exception e) { throw new InternalErrorException (e, loc); } if (!ec.IsInProbingMode) { compatibles.Add (type, am ?? EmptyExpression.Null); } return am; }
public BlockContext (ResolveContext rc, ExplicitBlock block, TypeSpec returnType) : this (rc.MemberContext, block, returnType) { if (rc.IsUnsafe) flags |= ResolveContext.Options.UnsafeScope; if (rc.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; if (rc.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (rc.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= ResolveContext.Options.ExpressionTreeConversion; if (rc.HasSet (ResolveContext.Options.BaseInitializer)) flags |= ResolveContext.Options.BaseInitializer; }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } var bc = ec as BlockContext; if (bc != null) aec.FlowOffset = bc.FlowOffset; var errors = ec.Report.Errors; bool res = Block.Resolve (ec.CurrentBranching, aec, null); if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; // // If e is synchronous the inferred return type is T // If e is asynchronous the inferred return type is Task<T> // if (block.IsAsync && ReturnType != null) { ReturnType = ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); } } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec.MemberContext, Block, ReturnType); aec.CurrentAnonymousMethod = ae; ResolveContext.FlagsHandle? aec_dispose = null; ResolveContext.Options flags = 0; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } if (ec.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (ec.IsUnsafe) flags |= ResolveContext.Options.UnsafeScope; if (ec.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= ResolveContext.Options.ExpressionTreeConversion; // HACK: Flag with 0 cannot be set if (flags != 0) aec_dispose = aec.Set (flags); var errors = ec.Report.Errors; bool res = Block.Resolve (ec.CurrentBranching, aec, Block.Parameters, null); if (aec.HasReturnLabel) return_label = aec.ReturnLabel; if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; } if (aec_dispose != null) { aec_dispose.Value.Dispose (); } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }