Example #1
0
				public Dispose (TemporaryVariable variable, LocalTemporary dispose, Expression expr, Statement statement, Location loc)
					: base (expr, statement, loc)
				{
					base.local_copy = variable;
					this.dispose = dispose;
				}
Example #2
0
			public override bool Resolve (BlockContext ec)
			{
				bool is_dynamic = expr.Type == InternalType.Dynamic;
				if (is_dynamic)
					expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc);

				var get_enumerator_mg = ResolveGetEnumerator (ec);
				if (get_enumerator_mg == null) {
					return false;
				}

				var get_enumerator = get_enumerator_mg.BestCandidate;
				var enumerator = new TemporaryVariable (get_enumerator.ReturnType, loc);
				enumerator.Resolve (ec);

				// Prepare bool MoveNext ()
				var move_next_mg = ResolveMoveNext (ec, get_enumerator);
				if (move_next_mg == null) {
					return false;
				}

				move_next_mg.InstanceExpression = enumerator;

				// Prepare ~T~ Current { get; }
				var current_prop = ResolveCurrent (ec, get_enumerator);
				if (current_prop == null) {
					return false;
				}

				var current_pe = new PropertyExpr (current_prop, loc) { InstanceExpression = enumerator }.Resolve (ec);
				if (current_pe == null)
					return false;

				VarExpr ve = var_type as VarExpr;
				if (ve != null) {
					// Infer implicitly typed local variable from foreach enumerable type
					var_type = new TypeExpression (current_pe.Type, var_type.Location);
				}

				var_type = var_type.ResolveAsTypeTerminal (ec, false);
				if (var_type == null)
					return false;

				var init = new Invocation (get_enumerator_mg, null);
				init.Resolve (ec);

				statement = new While (new BooleanExpression (new Invocation (move_next_mg, null)),
					new Body (var_type.Type, variable, current_pe, statement, loc), loc);

				var enum_type = enumerator.Type;

				//
				// Add Dispose method call when enumerator can be IDisposable
				//
				if (!enumerator.Type.ImplementsInterface (TypeManager.idisposable_type)) {
					if (!enum_type.IsSealed && !TypeManager.IsValueType (enum_type)) {
						//
						// Runtime Dispose check
						//
						var tv = new LocalTemporary (TypeManager.idisposable_type);
						statement = new Dispose (enumerator, tv, init, statement, loc);
					} else {
						//
						// No Dispose call needed
						//
						this.init = new SimpleAssign (enumerator, init);
						this.init.Resolve (ec);
					}
				} else {
					//
					// Static Dispose check
					//
					statement = new Dispose (enumerator, null, init, statement, loc);
				}

				return statement.Resolve (ec);
			}
Example #3
0
		protected virtual bool DoResolve (BlockContext ec)
		{
			expr = expr.Resolve (ec);
			if (expr == null)
				return false;

			if (!expr.Type.ImplementsInterface (TypeManager.idisposable_type) &&
				Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
				if (expr.Type != InternalType.Dynamic) {
					Using.Error_IsNotConvertibleToIDisposable (ec, expr);
					return false;
				}

				expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.idisposable_type, loc);
			}

			var expr_type = expr.Type;

			local_copy = new TemporaryVariable (expr_type, loc);
			local_copy.Resolve (ec);

			if (TypeManager.void_dispose_void == null) {
				TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
					TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
			}

			var dispose_mg = MethodGroupExpr.CreatePredefined (TypeManager.void_dispose_void, TypeManager.idisposable_type, loc);
			dispose_mg.InstanceExpression = TypeManager.IsNullableType (expr_type) ?
				new Cast (new TypeExpression (TypeManager.idisposable_type, loc), local_copy, loc).Resolve (ec) :
				local_copy;

			dispose_call = new StatementExpression (new Invocation (dispose_mg, null));

			// Add conditional call when disposing possible null variable
			if (!expr_type.IsStruct || TypeManager.IsNullableType (expr_type))
				dispose_call = new If (new Binary (Binary.Operator.Inequality, local_copy, new NullLiteral (loc), loc), dispose_call, loc);

			return dispose_call.Resolve (ec);
		}
Example #4
0
			public override bool Resolve (BlockContext ec)
			{
				copy = new TemporaryVariable (for_each.expr.Type, loc);
				copy.Resolve (ec);

				int rank = length_exprs.Length;
				Arguments list = new Arguments (rank);
				for (int i = 0; i < rank; i++) {
					counter [i] = new ArrayCounter (loc);
					counter [i].ResolveIncrement (ec);					

					if (rank == 1) {
						length_exprs [i] = new MemberAccess (copy, "Length").Resolve (ec);
					} else {
						lengths [i] = new TemporaryVariable (TypeManager.int32_type, loc);
						lengths [i].Resolve (ec);

						Arguments args = new Arguments (1);
						args.Add (new Argument (new IntConstant (i, loc)));
						length_exprs [i] = new Invocation (new MemberAccess (copy, "GetLength"), args).Resolve (ec);
					}

					list.Add (new Argument (counter [i]));
				}

				access = new ElementAccess (copy, list, loc).Resolve (ec);
				if (access == null)
					return false;

				Expression var_type = for_each.type;
				VarExpr ve = var_type as VarExpr;
				if (ve != null) {
					// Infer implicitly typed local variable from foreach array type
					var_type = new TypeExpression (access.Type, ve.Location);
				}

				var_type = var_type.ResolveAsTypeTerminal (ec, false);
				if (var_type == null)
					return false;

				conv = Convert.ExplicitConversion (ec, access, var_type.Type, loc);
				if (conv == null)
					return false;

				bool ok = true;

				ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
				ec.CurrentBranching.CreateSibling ();

				for_each.variable = for_each.variable.ResolveLValue (ec, conv);
				if (for_each.variable == null)
					ok = false;

				ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
				if (!statement.Resolve (ec))
					ok = false;
				ec.EndFlowBranching ();

				// There's no direct control flow from the end of the embedded statement to the end of the loop
				ec.CurrentBranching.CurrentUsageVector.Goto ();

				ec.EndFlowBranching ();

				return ok;
			}
Example #5
0
		public override bool Resolve (BlockContext ec)
		{
			expr = expr.Resolve (ec);
			if (expr == null)
				return false;

			if (!TypeManager.IsReferenceType (expr.Type)){
				ec.Report.Error (185, loc,
					      "`{0}' is not a reference type as required by the lock statement",
					      TypeManager.CSharpName (expr.Type));
				return false;
			}

			ec.StartFlowBranching (this);
			bool ok = Statement.Resolve (ec);
			ec.EndFlowBranching ();

			ok &= base.Resolve (ec);

			// Avoid creating libraries that reference the internal
			// mcs NullType:
			TypeSpec t = expr.Type;
			if (t == TypeManager.null_type)
				t = TypeManager.object_type;
			
			temp = new TemporaryVariable (t, loc);
			temp.Resolve (ec);

			if (TypeManager.void_monitor_enter_object == null || TypeManager.void_monitor_exit_object == null) {
				TypeSpec monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
				TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
					monitor_type, "Enter", loc, TypeManager.object_type);
				TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
					monitor_type, "Exit", loc, TypeManager.object_type);
			}
			
			return ok;
		}
Example #6
0
			public override bool Resolve (EmitContext ec)
			{
				enumerator_type = TypeManager.ienumerator_type;

				if (!ProbeCollectionType (ec, expr.Type)) {
					Error_Enumerator ();
					return false;
				}

				bool is_disposable = !enumerator_type.IsSealed ||
					TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type);

				VarExpr ve = var_type as VarExpr;
				if (ve != null) {
					// Infer implicitly typed local variable from foreach enumerable type
					var_type = new TypeExpression (get_current.PropertyInfo.PropertyType, var_type.Location);
				}

				var_type = var_type.ResolveAsTypeTerminal (ec, false);
				if (var_type == null)
					return false;
								
				enumerator = new TemporaryVariable (enumerator_type, loc);
				enumerator.Resolve (ec);

				init = new Invocation (get_enumerator, null);
				init = init.Resolve (ec);
				if (init == null)
					return false;

				Expression move_next_expr;
				{
					MemberInfo[] mi = new MemberInfo[] { move_next };
					MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
					mg.InstanceExpression = enumerator;

					move_next_expr = new Invocation (mg, null);
				}

				get_current.InstanceExpression = enumerator;

				Statement block = new CollectionForeachStatement (
					var_type.Type, variable, get_current, statement, loc);

				loop = new While (move_next_expr, block, loc);

				wrapper = is_disposable ?
					(Statement) new DisposableWrapper (this) :
					(Statement) new NonDisposableWrapper (this);
				return wrapper.Resolve (ec);
			}
Example #7
0
		public override bool Resolve (EmitContext ec)
		{
			expr = expr.Resolve (ec);
			if (expr == null)
				return false;

			expr_type = expr.Type;

			if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)) {
				if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
					Using.Error_IsNotConvertibleToIDisposable (expr);
					return false;
				}
			}

			local_copy = new TemporaryVariable (expr_type, loc);
			local_copy.Resolve (ec);

			ec.StartFlowBranching (this);

			bool ok = Statement.Resolve (ec);

			ec.EndFlowBranching ();

			ResolveReachability (ec);

			if (TypeManager.void_dispose_void == null) {
				TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
					TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
			}

			return ok;
		}
Example #8
0
        public override bool Resolve(BlockContext ec)
        {
            expr = expr.Resolve (ec);
            if (expr == null)
                return false;

            expr_type = expr.Type;

            if (!expr_type.ImplementsInterface (TypeManager.idisposable_type) &&
                Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
                if (expr_type != InternalType.Dynamic) {
                    Using.Error_IsNotConvertibleToIDisposable (ec, expr);
                    return false;
                }

                expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.idisposable_type, loc);
                expr_type = expr.Type;
            }

            local_copy = new TemporaryVariable (expr_type, loc);
            local_copy.Resolve (ec);

            ec.StartFlowBranching (this);

            bool ok = Statement.Resolve (ec);

            ec.EndFlowBranching ();

            ok &= base.Resolve (ec);

            if (TypeManager.void_dispose_void == null) {
                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
                    TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
            }

            return ok;
        }
Example #9
0
            public override bool Resolve(BlockContext ec)
            {
                enumerator_type = TypeManager.ienumerator_type;

                bool is_dynamic = expr.Type == InternalType.Dynamic;
                if (is_dynamic)
                    expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc);

                if (!ProbeCollectionType (ec, expr.Type)) {
                    Error_Enumerator (ec);
                    return false;
                }

                VarExpr ve = var_type as VarExpr;
                if (ve != null) {
                    // Infer implicitly typed local variable from foreach enumerable type
                    var_type = new TypeExpression (
                        is_dynamic ? InternalType.Dynamic : get_current.Type,
                        var_type.Location);
                }

                var_type = var_type.ResolveAsTypeTerminal (ec, false);
                if (var_type == null)
                    return false;

                enumerator = new TemporaryVariable (enumerator_type, loc);
                enumerator.Resolve (ec);

                init = new Invocation (get_enumerator, null);
                init = init.Resolve (ec);
                if (init == null)
                    return false;

                Expression move_next_expr;
                {
                    var mi = new List<MemberSpec> (1) { move_next };
                    MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
                    mg.InstanceExpression = enumerator;

                    move_next_expr = new Invocation (mg, null);
                }

                get_current.InstanceExpression = enumerator;

                Statement block = new CollectionForeachStatement (
                    var_type.Type, variable, get_current, statement, loc);

                loop = new While (new BooleanExpression (move_next_expr), block, loc);

                bool implements_idisposable = enumerator_type.ImplementsInterface (TypeManager.idisposable_type);
                if (implements_idisposable || !enumerator_type.IsSealed) {
                    wrapper = new DisposableWrapper (this, implements_idisposable);
                } else {
                    wrapper = new NonDisposableWrapper (this);
                }

                return wrapper.Resolve (ec);
            }