/// <summary> /// Initializes a new instance of the <see cref="PropertyWeavingPlan"/> class. /// </summary> /// <param name="getterPlan">Weaving plan for getter method.</param> /// <param name="setterPlan">Weaving plan for setter method.</param> public PropertyWeavingPlan(IWeavingPlan getterPlan, IWeavingPlan setterPlan) { // with possibility to be empty, plan may be empty if the population process isn't monitored // and the code looks dirty to monitor weaving plan population // so allow plan to be empty, handle empty plan at weaving phase // no empty checking here GetterPlan = getterPlan; SetterPlan = setterPlan; }
/// <summary> /// Weave the method. /// </summary> /// <param name="method">Method to be weaved.</param> /// <param name="plan">Weaving plan.</param> /// <param name="propertyName">Name of the property in case the method is a getter or setter method.</param> /// <param name="statistics">Weaving statistics.</param> public void Weave(MethodDefinition method, IWeavingPlan plan, string propertyName, ICanAddMethodWeavingRecord statistics) { #if DEBUG if (method == null) { throw new ArgumentNullException("method"); } if (plan == null) { throw new ArgumentNullException("plan"); } #endif context.Reset(); var methodSignature = method.GetSignature(); var processor = method.Body.GetILProcessor(); AddLocalVariables(method, processor, plan); WeaveEntryJoinPoint(method, processor, plan.GetAdvices(JoinPoint.Entry), statistics, propertyName, methodSignature); WeaveExceptionJoinPoint(method, processor, plan.GetAdvices(JoinPoint.Exception), statistics, propertyName, methodSignature); WeaveExitJoinPoint(method, processor, plan.GetAdvices(JoinPoint.Exit), statistics, propertyName, methodSignature); WeaveSwitchInitialization(method, processor); }
private void AddLocalVariables(MethodDefinition method, ILProcessor processor, IWeavingPlan plan) { var instructions = new List <Instruction>(); // ordering of declarations of the local variables matters when applying switches in the end if (plan.NeedContextVariable()) { AddExecutionContextVariable(method, instructions, processor); } if (plan.NeedExecutionVariable()) { AddExecutionVariable(method, instructions, processor); } if (plan.NeedExceptionVariable()) { AddExceptionVariable(method); } if (plan.NeedReturnVariable()) { AddReturnVariable(method, instructions, processor); } if (NeedToStoreReturnValueAsLocalVariable(method, plan)) { AddReturnValueVariable(method); } if (NeedHasExceptionVariable(method, plan)) { AddHasExceptionVariable(method, instructions, processor); } CompleteAddingLocalVariableInstructions(method, instructions, processor); }
private static bool NeedHasExceptionVariable(MethodDefinition method, IWeavingPlan plan) => plan.NeedHasExceptionVariable() || (plan.NeedReturnVariable() && !method.IsVoidReturn());
private static bool NeedToStoreReturnValueAsLocalVariable(MethodDefinition method, IWeavingPlan plan) => !method.IsVoidReturn() && plan.NeedToStoreReturnValueAsLocalVariable();
/// <summary> /// Initializes a new instance of of <see cref="IPropertyWeavingPlan"/>. /// </summary> /// <param name="getterPlan">Weaving plan for getter method.</param> /// <param name="setterPlan">Weaving plan for setter method.</param> /// <returns>The <see cref="IPropertyWeavingPlan"/> initialized.</returns> internal static IPropertyWeavingPlan InitializePropertyWeavingPlan(IWeavingPlan getterPlan, IWeavingPlan setterPlan) => new PropertyWeavingPlan(getterPlan, setterPlan);
/// <summary> /// Checks if <see cref="CrossCutterN.Base.Metadata.IReturn"/> variable is needed. /// </summary> /// <param name="plan">The execution plan to be checked.</param> /// <returns>True if <see cref="CrossCutterN.Base.Metadata.IReturn"/> variable is needed, false if not.</returns> public static bool NeedReturnVariable(this IWeavingPlan plan) => plan.ParameterFlag.Contains(AdviceParameterFlag.Return);
/// <summary> /// Checks if Exception variable is needed. /// </summary> /// <param name="plan">The execution plan to be checked.</param> /// <returns>True if Exception variable is needed, false if not.</returns> public static bool NeedExceptionVariable(this IWeavingPlan plan) => plan.ParameterFlag.Contains(AdviceParameterFlag.Exception);
/// <summary> /// Checks if <see cref="CrossCutterN.Base.Metadata.IExecutionContext"/> variable is needed. /// </summary> /// <param name="plan">The execution plan to be checked.</param> /// <returns>True if <see cref="CrossCutterN.Base.Metadata.IExecutionContext"/> variable is needed, false if not.</returns> public static bool NeedContextVariable(this IWeavingPlan plan) => plan.ParameterFlag.Contains(AdviceParameterFlag.Context);
/// <summary> /// Checks if return value needs to be stored as local variable during weaving. /// </summary> /// <param name="plan">The weaving plan to be checked.</param> /// <returns>True if return value needs to be stored as local variable, false if not.</returns> public static bool NeedToStoreReturnValueAsLocalVariable(this IWeavingPlan plan) { var pointCut = plan.PointCut; return(pointCut.Contains(JoinPoint.Exception) || pointCut.Contains(JoinPoint.Exit)); }
/// <summary> /// Checks whether a weaving plan is empty. /// </summary> /// <param name="plan">The weaving plan to be checked.</param> /// <returns>True if the weaving plan is empty, false if not.</returns> public static bool IsEmpty(this IWeavingPlan plan) => !plan.PointCut.Any();