Create closure class, including all its members for an iterator method and rewrite the body of the iterator method. Specifically, we: 1) creates a closure class that implements: IEnumerator, generic and nongeneric versions, IEnumerable, generic and nongeneric versions, and IDisposable. The generic versions of IEnumerator and IEnumerator is instantiated by a type T that is used to instantiate the return type of the iterator method. The members of the closure class include: 1.1) fields corresponding to every parameter and local variables. 1.2) fields that manages the state machine: __current and __state, and a currentThreadId field. 1.3) a constructor that takes one int argument. 1.4) methods that are required by the interfaces of the closure class: MoveNext, Reset, GetEnumerator, Current getter, and DisposeMethod. 2) creates the new body of the iterator method: which returns a local variable that holds a new object of the closure class, with the fields of the closure class that correspond to the parameters (including the self parameter if applicable) initialized. 3) transforms the body, which should now not contain any annonymous delegates, into the body of the MoveNext method of the closure class. This includes: 3.1) every local/parameter reference -> this.field reference 3.2) every yield return or yield break -> assignment to current and return true or false, respectively. 3.3) a switch statement for the state machine, with state values corresponds to each yield return/yield break. 3.4) try statement for foreach if the iterator method body uses one. 4) If the iterator method has a type parameter, so will the closure class. Make sure in the closure class only the right type parameter is referenced.
示例#1
0
 /// <summary>
 /// Given the body of an iterator method <paramref name="body"/>, this method try to compile its body.
 /// 
 /// Specifically, this method:
 /// 1) creates a closure class that implements: IEnumerator, generic and nongeneric versions,
 /// IEnumerable, generic and nongeneric versions, and IDisposable. The generic versions of IEnumerator
 /// and IEnumerator is instantiated by a type T that is used to instantiate the return type of
 /// the iterator method. The members of the closure class include:
 /// 1.1) fields corresponding to every parameter and local variables.
 /// 1.2) fields that manages the state machine: __current and __state, and a currentThreadId field.
 /// 1.3) a constructor that takes one int argument.  
 /// 1.4) methods that are required by the interfaces of the closure class: MoveNext, Reset,
 /// GetEnumerator, Current getter, and DisposeMethod. (GetEnumerator is needed only if the iterator's type is IEnumerable and not IEnumerator.)
 /// 2) creates the new body of the iterator method: which returns a local variable that holds a new object of the closure class, with the fields of 
 /// the closure class that correspond to the parameters (including the self parameter if applicable)
 /// initialized. 
 /// 3) transforms the body, which should now not contain any annonymous delegates, into the body of the 
 /// MoveNext method of the closure class. This includes:
 /// 3.1) every local/parameter reference -> this.field reference
 /// 3.2) every yield return or yield break -> assignment to current and return true or false, respectively.
 /// 3.3) a switch statement for the state machine, with state values corresponds to each yield return/yield break
 /// 3.4) a try block if an iterator is created in the body. 
 /// 4) If the iterator method has a type parameter, so will the closure class. Make sure in the closure class only
 /// the right type parameter is referenced. 
 /// </summary>
 /// <param name="body">The method body to be normalized</param>
 /// <param name="method">Method definition that owns the body</param>
 /// <param name="privateHelperTypes">List of helper types generated when compiling <paramref name="method">method</paramref>/></param>
 /// <returns></returns>
 private BlockStatement GetNormalizedIteratorBody(IBlockStatement body, IMethodDefinition method, List<ITypeDefinition> privateHelperTypes) {
   IteratorClosureGenerator iteratorClosureGenerator = new IteratorClosureGenerator(method, privateHelperTypes, this.host, this.sourceLocationProvider);
   return iteratorClosureGenerator.CompileIterator(body);
 }