C# Class Microsoft.Cci.MutableCodeModel.IteratorClosureGenerator

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.
显示文件 Open project: visualmutator/visualmutator Class Usage Examples

Private Properties

Property Type Description
BuildStateMachine BlockStatement
CompileIterator BlockStatement
CreateDisposeMethod void
CreateGetEnumeratorMethodGeneric void
CreateGetEnumeratorMethodNonGeneric void
CreateIteratorClosure IteratorClosureInformation
CreateIteratorClosureConstructor void
CreateIteratorClosureFields void
CreateIteratorClosureMethods void
CreateIteratorClosureProperties void
CreateMoveNextMethod void
CreateNewIteratorMethodBody BlockStatement
CreateResetMethod void
GetBodyOfGenericGetEnumerator BlockStatement
GetClosureEnumeratorTypeArguments IEnumerable
GetClosureTypeReferenceFromIterator ITypeReference
GetFieldReference IFieldReference
GetLocalOrParameterType ITypeReference
GetMethodReference IMethodReference
IteratorClosureGenerator Microsoft.Cci.MutableCodeModel
TranslateIteratorMethodBodyToMoveNextBody IBlockStatement

Private Methods

Method Description
BuildStateMachine ( IteratorClosureInformation iteratorClosure, BlockStatement oldBody, ILabeledStatement>.Dictionary stateEntries ) : BlockStatement

Build the state machine. We start from state 0. For each yield return, we assign a unique state, which we call continueing state. For a yield return assigned with state x, we move the state machine from the previous state to x. Whenever we see a yield break, we transit the state to -1. When we return from state x, we jump to a label that is inserted right after the previous yield return (that is assigned with state x).

CompileIterator ( IBlockStatement block ) : BlockStatement

Compile the method body, represented by block. It creates the closure class and all its members and creates a new body for the iterator method.

CreateDisposeMethod ( IteratorClosureInformation iteratorClosure ) : void

DisposeMethod method. Currently the method body does nothing.

CreateGetEnumeratorMethodGeneric ( IteratorClosureInformation iteratorClosure ) : void

Create the generic version of the GetEnumerator for the iterator closure class.

CreateGetEnumeratorMethodNonGeneric ( IteratorClosureInformation iteratorClosure ) : void

Create the non-generic version of GetEnumerator and add it to the member list of iterator closure class.

CreateIteratorClosure ( BlockStatement blockStatement ) : IteratorClosureInformation

Create the iterator closure class and add it to the private helper types list.

CreateIteratorClosureConstructor ( IteratorClosureInformation iteratorClosure ) : void

Create the constuctor of the iterator class. The pseudo-code is: Ctor(int state) { object.Ctor(); this.state = state; this.threadid = Thread.CurrentThread.ManagedThreadId; }

CreateIteratorClosureFields ( IteratorClosureInformation iteratorClosure ) : void

Create fields for the closure class, which include fields for captured variables and fields for maintaining the state machine.

CreateIteratorClosureMethods ( IteratorClosureInformation iteratorClosure, BlockStatement blockStatement ) : void

Create the methods of the iterator closure.

CreateIteratorClosureProperties ( IteratorClosureInformation iteratorClosure ) : void

Create two properties: object Current and T Current as the closure class implements both the generic and non-generic version of ienumerator. Current Implementation generates getters, but not the property.

CreateMoveNextMethod ( IteratorClosureInformation iteratorClosure, BlockStatement blockStatement ) : void

Create the MoveNext method. This method sets up metadata and calls TranslateIteratorMethodBodyToMoveNextBody to compile the body.

CreateNewIteratorMethodBody ( IteratorClosureInformation iteratorClosure ) : BlockStatement

Create the new body of the iterator method.

Pseudo code: iteratorClosureLocal = new Closure(0); iteratorClosureLocal.field = parameter; // for each parameter including this. return iteratorClosureLocal;

CreateResetMethod ( IteratorClosureInformation iteratorClosure ) : void

Create the Reset method. Like in CSC, this method contains nothing.

GetBodyOfGenericGetEnumerator ( IteratorClosureInformation iteratorClosure ) : BlockStatement

Create the body of the generic version of GetEnumerator for the iterator closure class. The body's pseudo code. { if (Thread.CurrentThread.ManagedThreadId == this.l_initialThreadId AND this.state == -2) { this.state = 0; return this; } else { return a new copy of the iterator instance with state being zero. } }

GetClosureEnumeratorTypeArguments ( ITypeReference methodTypeReference ) : IEnumerable

Find the type argument of the IEnumerable generic type implemented by a methodTypeReference, or System.Object if methodTypeReference implements the non-generic IEnumerable.

GetClosureTypeReferenceFromIterator ( IteratorClosureInformation iteratorClosure ) : ITypeReference

Instantiate the closure class using the generic method parameters of the iterator method, if any.

GetFieldReference ( IteratorClosureInformation iteratorClosure, IFieldDefinition fieldDefinition ) : IFieldReference

Instantiate a closure class field using the generic method parameters of the iterator method, if any. Code Review: cache the result of GetClosureTypeReferenceFromIterator.

GetLocalOrParameterType ( object obj ) : ITypeReference

Return the type of the parameter (excluding this) or local variable represented by obj.

GetMethodReference ( IteratorClosureInformation iteratorClosure, IMethodDefinition methodDefinition ) : IMethodReference

Instantiate a closure class method using the generic method parameters of the iterator method, if any.

IteratorClosureGenerator ( IMethodDefinition method, List privateHelperTypes, IMetadataHost host, ISourceLocationProvider sourceLocationProvider ) : Microsoft.Cci.MutableCodeModel

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.

TranslateIteratorMethodBodyToMoveNextBody ( IteratorClosureInformation iteratorClosure, BlockStatement blockStatement ) : IBlockStatement

Create method body of the MoveNext from a copy of the body of the iterator method. First we substitute the locals/parameters with closure fields, and generic method type parameter of the iterator method with generic type parameters of the closure class (if any). Then, we build the state machine.