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); }
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); }