HasSet() public method

public HasSet ( Options options ) : bool
options Options
return bool
Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }
Example #6
0
 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);
     }
 }
Example #7
0
        protected override Expression DoResolve(ResolveContext rc)
        {
            if (!rc.HasSet(ResolveContext.Options.DontSetConditionalAccessReceiver))
            {
                conditionalAccessReceiver = HasConditionalAccess() || Arguments [0].Expr.HasConditionalAccess();
            }

            return(base.DoResolve(rc));
        }
Example #8
0
        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));
        }
Example #9
0
        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));
        }
Example #10
0
        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;
            }
        }
Example #11
0
        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));
        }
Example #12
0
		//
		// 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;
		}
Example #13
0
		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);
		}
Example #14
0
		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);
		}
Example #15
0
		/// <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;
		}
Example #16
0
        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));
        }
Example #17
0
		protected override Expression DoResolve (ResolveContext rc)
		{
			if (!rc.HasSet (ResolveContext.Options.DontSetConditionalAccessReceiver))
				conditionalAccessReceiver = HasConditionalAccess () || Arguments [0].Expr.HasConditionalAccess ();

			return base.DoResolve (rc);
		}
Example #18
0
        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;
        }
Example #19
0
        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);
        }
Example #20
0
		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;
		}
Example #21
0
		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);
		}
Example #23
0
        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);
        }
Example #24
0
 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);
 }
Example #25
0
        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;
        }
Example #26
0
		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;
		}
Example #27
0
		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;
		}
Example #28
0
		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;
		}
Example #29
0
        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);
		}
Example #31
0
        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;
        }
Example #32
0
		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;
		}
Example #33
0
		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);
		}
Example #34
0
		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;
		}
Example #35
0
		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;
		}
Example #36
0
        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;
		}
Example #38
0
File: assign.cs Project: dyxu/vimrc
		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);
		}
Example #39
0
        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);
        }
Example #40
0
		//
		// 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;
		}
Example #41
0
		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;
		}
Example #42
0
		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;
		}
Example #43
0
		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;
		}