private void EmitUsingDefinitionValue(ILGenerator ilGenerator, FluentActionDefinition fluentActionDefinition, FluentActionUsingDefinition usingDefinition, Dictionary <int, int> methodParameterIndices, StateMachineState state, int stateIndex, int handlerInStateIndex) { if (usingDefinition.IsMethodParameter) { var usingDefinitionHash = usingDefinition.GetHashCode(); var methodParameterIndex = methodParameterIndices[usingDefinitionHash]; ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, MethodParameterFields[methodParameterIndex - 1]); } else if (usingDefinition.IsControllerProperty) { ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, ParentField); ilGenerator.Emit(OpCodes.Callvirt, typeof(Controller).GetProperty(usingDefinition.ControllerPropertyName).GetGetMethod()); } else if (usingDefinition is FluentActionUsingPropertyDefinition) { var propertyName = ((FluentActionUsingPropertyDefinition)usingDefinition).PropertyName; var parentType = fluentActionDefinition.ParentType ?? typeof(Controller); var property = parentType.GetProperty(propertyName); if (property == null) { throw new Exception($"Could not find property {propertyName} on type {parentType.FullName}."); } var propertyGetMethod = property.GetGetMethod(); if (propertyGetMethod == null) { throw new Exception($"Missing public get method on property {propertyName} on type {parentType.FullName}."); } ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, ParentField); ilGenerator.Emit(OpCodes.Callvirt, propertyGetMethod); } else if (usingDefinition is FluentActionUsingParentDefinition) { ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, ParentField); } else if (usingDefinition is FluentActionUsingResultDefinition) { FieldBuilder resultFieldToLoad; if (handlerInStateIndex > 0) { resultFieldToLoad = state.Handlers[handlerInStateIndex - 1].ResultField; } else { resultFieldToLoad = States[stateIndex - 1].ResultField; } ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, resultFieldToLoad); if (resultFieldToLoad.FieldType.IsValueType) { ilGenerator.Emit(OpCodes.Box, resultFieldToLoad.FieldType); } } else { throw new Exception($"Got unknown using definition: {usingDefinition.GetType()}"); } }
private void EmitUsingDefinitionValue( ILGenerator ilGenerator, FluentActionUsingDefinition usingDefinition, Dictionary <int, int> methodParameterIndices, LocalBuilder localVariableForPreviousReturnValue) { var ilHandle = new IlHandle { Generator = ilGenerator }; var usingDefinitionHash = usingDefinition.GetHashCode(); var methodParameterIndex = methodParameterIndices.ContainsKey(usingDefinitionHash) ? methodParameterIndices[usingDefinitionHash] : -1; if (usingDefinition.IsMethodParameter) { ilHandle.Generator.Emit(OpCodes.Ldarg, methodParameterIndex); } else if (usingDefinition.IsControllerProperty) { ilHandle.Generator.Emit(OpCodes.Ldarg_0); ilHandle.Generator.Emit(OpCodes.Callvirt, typeof(Controller).GetProperty(usingDefinition.ControllerPropertyName).GetGetMethod()); } else if (usingDefinition is FluentActionUsingPropertyDefinition) { var propertyName = ((FluentActionUsingPropertyDefinition)usingDefinition).PropertyName; var parentType = FluentActionDefinition.ParentType ?? typeof(Controller); var property = parentType.GetProperty(propertyName); if (property == null) { throw new Exception($"Could not find property {propertyName} on type {parentType.FullName}."); } var propertyGetMethod = property.GetGetMethod(); if (propertyGetMethod == null) { throw new Exception($"Missing public get method on property {propertyName} on type {parentType.FullName}."); } ilHandle.Generator.Emit(OpCodes.Ldarg_0); ilHandle.Generator.Emit(OpCodes.Callvirt, propertyGetMethod); } else if (usingDefinition is FluentActionUsingParentDefinition) { ilHandle.Generator.Emit(OpCodes.Ldarg_0); } else if (usingDefinition is FluentActionUsingResultDefinition) { if (localVariableForPreviousReturnValue == null) { throw new Exception("Cannot use previous result from handler as no previous result exists."); } ilHandle.Generator.Emit(OpCodes.Ldloc, localVariableForPreviousReturnValue); if (localVariableForPreviousReturnValue.LocalType.IsValueType) { ilHandle.Generator.Emit(OpCodes.Box, localVariableForPreviousReturnValue.LocalType); } } else { throw new Exception($"Got unknown using definition: {usingDefinition.GetType()}"); } }