public static bool CheckContext (EmitContext ec, Location loc)
{
- if (ec.InFinally){
+ if (ec.CurrentBranching.InFinally (true)){
Report.Error (-208, loc, "yield statement can not appear in finally clause");
return false;
}
- if (ec.InCatch){
+ if (ec.CurrentBranching.InCatch ()){
Report.Error (-209, loc, "yield statement can not appear in the catch clause");
return false;
}
return false;
if (!CheckContext (ec, loc))
return false;
+
Type iterator_type = IteratorHandler.Current.IteratorType;
if (expr.Type != iterator_type){
return true;
}
- protected override bool DoEmit (EmitContext ec)
+ protected override void DoEmit (EmitContext ec)
{
IteratorHandler.Current.MarkYield (ec, expr);
-
- return false;
}
}
if (!Yield.CheckContext (ec, loc))
return false;
- ec.CurrentBranching.Goto ();
+ ec.CurrentBranching.CurrentUsageVector.Goto ();
return true;
}
- protected override bool DoEmit (EmitContext ec)
+ protected override void DoEmit (EmitContext ec)
{
IteratorHandler.Current.EmitYieldBreak (ec.ig, true);
- return false;
}
}
Create_Current ();
Create_Dispose ();
- if (return_type == TypeManager.ienumerable_type){
+ if (IsIEnumerable (return_type)){
Create_GetEnumerator ();
RootContext.RegisterHelperClass (enumerable_proxy_class);
}
// Create the proxy class type.
handler.MakeEnumeratorProxy ();
- if (handler.return_type == TypeManager.ienumerable_type)
+ if (IsIEnumerable (handler.return_type))
handler.MakeEnumerableProxy ();
type = handler.return_type;
{
handler.LoadArgs (ec.ig);
- if (handler.return_type == TypeManager.ienumerable_type)
+ if (IsIEnumerable (handler.return_type))
ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) handler.enumerable_proxy_constructor);
else
ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) handler.enumerator_proxy_constructor);
return ret_val;
}
}
+
+ static bool IsIEnumerable (Type t)
+ {
+ return t == TypeManager.ienumerable_type || TypeManager.ImplementsInterface (t, TypeManager.ienumerable_type);
+ }
+
+ static bool IsIEnumerator (Type t)
+ {
+ return t == TypeManager.ienumerator_type || TypeManager.ImplementsInterface (t, TypeManager.ienumerator_type);
+ }
//
// Returns the new block for the method, or null on failure
//
public Block Setup (Block block)
{
- if (return_type != TypeManager.ienumerator_type &&
- return_type != TypeManager.ienumerable_type){
+ if (!(IsIEnumerator (return_type) || IsIEnumerable (return_type))){
Report.Error (
-205, loc, String.Format (
- "The method `{0}' contains a yield statement, but has an invalid return type for an iterator",
- name));
+ "The method `{0}' contains a yield statement, but has an invalid return type for an iterator `{1}'",
+ name, TypeManager.CSharpName (return_type)));
return null;
}