protected override Expression ResolveInitializer (BlockContext bc, LocalVariable li, Expression initializer) { if (li.Type == InternalType.Dynamic) { initializer = initializer.Resolve (bc); if (initializer == null) return null; // Once there is dynamic used defer conversion to runtime even if we know it will never succeed Arguments args = new Arguments (1); args.Add (new Argument (initializer)); initializer = new DynamicConversion (TypeManager.idisposable_type, 0, args, initializer.Location).Resolve (bc); if (initializer == null) return null; var var = LocalVariable.CreateCompilerGenerated (TypeManager.idisposable_type, bc.CurrentBlock, loc); dispose_call = CreateDisposeCall (bc, var); dispose_call.Resolve (bc); return base.ResolveInitializer (bc, li, new SimpleAssign (var.CreateReferenceExpression (bc, loc), initializer, loc)); } if (li == Variable) { CheckIDiposableConversion (bc, li, initializer); dispose_call = CreateDisposeCall (bc, li); dispose_call.Resolve (bc); } return base.ResolveInitializer (bc, li, initializer); }
protected override Expression ResolveInitializer (BlockContext bc, LocalVariable li, Expression initializer) { Assign assign; if (li.Type == InternalType.Dynamic) { initializer = initializer.Resolve (bc); if (initializer == null) return null; initializer = Convert.ImplicitConversionRequired (bc, initializer, TypeManager.idisposable_type, loc); if (initializer == null) return null; var var = LocalVariable.CreateCompilerGenerated (TypeManager.idisposable_type, bc.CurrentBlock, loc); assign = new SimpleAssign (var.CreateReferenceExpression (bc, loc), initializer, loc); assign.ResolveStatement (bc); dispose_call = CreateDisposeCall (bc, var); dispose_call.Resolve (bc); return assign; } if (li == Variable) { CheckIDiposableConversion (bc, li, initializer); dispose_call = CreateDisposeCall (bc, li); dispose_call.Resolve (bc); } return base.ResolveInitializer (bc, li, initializer); }
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); }