public MessageArgumentsFormatter(MethodBodyTransformationContext context)
 {
     this.context = context;
     this.targetMethod = context.TargetElement as MethodDefDeclaration;
     if (this.targetMethod == null)
     {
         throw new InvalidOperationException("Target element is not a method");
     }
 }
 public GuardPropertyEqualityMethodBodyWrappingImplementation(IPropertyTransformationContext transformationContext, AspectInfrastructureTask task, MethodBodyTransformationContext context)
     : base(task, context)
 {
     if (transformationContext == null) throw new ArgumentNullException("transformationContext");
     _transformationContext = transformationContext;
     _assets =
         _transformationContext.Module.Cache.GetItem(
             () => new TransformationAssets(_transformationContext.Module));
 }
 public MessageArgumentsFormatter(MethodBodyTransformationContext context)
 {
     this.context      = context;
     this.targetMethod = context.TargetElement as MethodDefDeclaration;
     if (this.targetMethod == null)
     {
         throw new InvalidOperationException("Target element is not a method");
     }
 }
 protected ComposedMethodBodyWrappingImplementation(MethodBodyWrappingImplementationOptions wrappingImplementationOptions, AspectInfrastructureTask task, MethodBodyTransformationContext context)
     : base(task, context)
 {
     if (wrappingImplementationOptions == null) throw new ArgumentNullException("wrappingImplementationOptions");
     _wrappingImplementationOptions = wrappingImplementationOptions;
     try {
         CompositionInitializer.SatisfyImports(this);
     } catch (Exception ex) {
         throw;
     }
 }
        public static void AddPropertyGuard(PropertyDeclaration property, MethodBodyTransformationContext context, InstructionBlock block, InstructionWriter writer)
        {
            var propertyType = property.PropertyType;
            var methodBody = block.MethodBody;

            var sequence = block.AddInstructionSequence(null, NodePosition.After, null);
            if (sequence == null) return;

            var oldValueVariable =
                block.DefineLocalVariable(propertyType, string.Format("old{0}Value", property.Name));
            var assets = GetTransformationAssets(property.Module);

            writer.AttachInstructionSequence(sequence);
            var isLocationBinding = CheckIfIsLocationBinding(methodBody,assets);
            if (isLocationBinding) {
                writer.AssignValue_LocalVariable(oldValueVariable
                    , () => writer.Call_MethodOnTarget(property.GetGetter()
                        ,
                        () => {
                            //Load the instance parameter of the SetValue method
                            //and convert it to the type
                            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                            //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature);
                            writer.EmitInstructionType(OpCodeNumber.Ldobj, assets.ObjectTypeSignature);
                            writer.EmitConvertFromObject(property.Parent);
                        }
                    )
                );
                //On the location binding the value parameter is at psotion 3
                writer.EmitInstruction(OpCodeNumber.Ldarg_3);
            } else {
                writer.AssignValue_LocalVariable(oldValueVariable,
                                                    () => writer.Get_PropertyValue(property));
                //For a normal property the value parameter is at position 1
                writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            }
            if (propertyType.IsStruct()) {
                writer.EmitInstructionType(OpCodeNumber.Box, propertyType);
            }
            writer.Box_LocalVariableIfNeeded(oldValueVariable);
            var isPrimitive = propertyType.IsPrimitive();
            if (isPrimitive) {
                writer.Compare_Primitives();
            } else {
                //TODO: Try and use the equality operator when present
                writer.Compare_Objects(assets.ObjectEqualsMethod);
            }
            //writer.Leave_IfTrue(_context.LeaveBranchTarget);
            writer.Leave_IfTrue(context.LeaveBranchTarget);
            writer.DetachInstructionSequence();
        }
 public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context)
     : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context)
 {
     this.transformationInstance = transformationInstance;
     this.backendInstance        = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance);
     this.options             = new ConfigurationOptions(this.transformationInstance.AspectWeaverInstance);
     this.argumentsFormatter  = new MessageArgumentsFormatter(context);
     this.methodMappingWriter = context.MethodMapping.CreateWriter();
 }
            public override void Implement(MethodBodyTransformationContext context)
            {
                Implementation implementation = new Implementation(this, context);

                implementation.Implement();
            }
 public EnhancePropertySetterMethodBodyWrappingImplementation(IPropertyTransformationContext transformationContext, AspectInfrastructureTask task, MethodBodyTransformationContext context)
     : base(task, context)
 {
     if (transformationContext == null) throw new ArgumentNullException("transformationContext");
     _transformationContext = transformationContext;
     _assets =
         _transformationContext.Module.Cache.GetItem(
             () => new TransformationAssets(_transformationContext.Module));
     _stringTypeSignature = _transformationContext.Module.Cache.GetIntrinsic(typeof(string));
 }
Пример #9
0
 public Visitor(Instance instance, MethodBodyTransformationContext context)
 {
     this.instance = instance;
     this.context  = context;
 }
Пример #10
0
 public override void Implement(MethodBodyTransformationContext context)
 {
     context.InstructionBlock.MethodBody.Visit(new[] { new Visitor(this, context) });
 }
                public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context)
                    : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context)
                {
                    this.transformationInstance = transformationInstance;
                    this.backendInstance        = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance);

                    // todo fix configuration
                    this.onEntryOptions     = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnEntryOptions);
                    this.onSuccessOptions   = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnSuccessOptions);
                    this.onExceptionOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnExceptionOptions);
                }
 public override void Implement(MethodBodyTransformationContext context)
 {
     Implementation implementation = new Implementation(this, context);
     implementation.Implement();
 }
 public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context)
     : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context)
 {
     this.transformationInstance = transformationInstance;
     this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance);
     this.options = new ConfigurationOptions(this.transformationInstance.AspectWeaverInstance);
     this.argumentsFormatter = new MessageArgumentsFormatter(context);
     this.methodMappingWriter = context.MethodMapping.CreateWriter();
 }
            private void AddGuard(MethodBodyTransformationContext context)
            {
                var property = Property;
                var propertyType = property.PropertyType;

                var methodBody = context.InstructionBlock.MethodBody;
                methodBody.InitLocalVariables = true;
                Instruction firstInstruction;
                InstructionBlock firstBlockWithInstruction = null;
                InstructionSequence firstSequenceWithInstruction = null;
                methodBody.ForEachInstruction(rdr => {
                    //if (rdr.CurrentInstruction != null && rdr.CurrentInstruction.OpCodeNumber == OpCodeNumber.Nop)
                    //    return true;
                    firstInstruction = rdr.CurrentInstruction;
                    firstSequenceWithInstruction = rdr.CurrentInstructionSequence;
                    firstBlockWithInstruction = rdr.CurrentInstructionBlock;
                    //firstSequenceWithInstruction.SplitAroundReaderPosition(rdr, out beforeSequence, out afterSequence);
                    return false;
                });

                if(firstSequenceWithInstruction == null) return;
                var beforeSequence = firstBlockWithInstruction
                    .AddInstructionSequence(null, NodePosition.Before,firstSequenceWithInstruction);

                var isLocationBinding = CheckIfIsLocationBinding(methodBody);
                var writer = new InstructionWriter();
                if(beforeSequence != null) {
                    var oldValueVariable = firstBlockWithInstruction
                        .DefineLocalVariable(propertyType, string.Format("old{0}Value",property.Name));

                    writer.AttachInstructionSequence(beforeSequence);
                    if(isLocationBinding) {
                        writer.AssignValue_LocalVariable(oldValueVariable
                            , () => writer.Call_MethodOnTarget(property.GetGetter(),
                                () => {
                                    //Load the instance parameter of the SetValue method
                                    //and convert it to the type
                                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                                    //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature);
                                    writer.EmitInstructionType(OpCodeNumber.Ldobj, Assets.ObjectTypeSignature);
                                    writer.EmitConvertFromObject(property.Parent);
                                }
                            )
                        );
                        //On the location binding the value parameter is at psotion 3
                        writer.EmitInstruction(OpCodeNumber.Ldarg_3);
                    }else {
                        writer.AssignValue_LocalVariable(oldValueVariable,
                                                         () => writer.Get_PropertyValue(property));
                        //For a normal property the value parameter is at position 1
                        writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    }
                    if (propertyType.IsStruct()) {
                        writer.EmitInstructionType(OpCodeNumber.Box, propertyType);
                    }
                    writer.Box_LocalVariableIfNeeded(oldValueVariable);
                    var isPrimitive = propertyType.IsPrimitive();
                    if (isPrimitive) {
                        writer.Compare_Primitives();
                    } else {
                        //TODO: Try and use the equality operator when present
                        writer.Compare_Objects(Assets.ObjectEqualsMethod);
                    }
                    //writer.Leave_IfTrue(_context.LeaveBranchTarget);
                    writer.Leave_IfTrue(context.LeaveBranchTarget);
                    writer.DetachInstructionSequence();
                }
            }
 public override void Implement(MethodBodyTransformationContext context)
 {
     AddSymJoinPoint(context);
     AddGuard(context);
     //context.InstructionBlock.MethodBody.Visit(new IMethodBodyVisitor[] { new Visitor(this, context) });
 }
 public override void Implement(MethodBodyTransformationContext context)
 {
     var methodWrapper = new EnhancePropertySetterMethodBodyWrappingImplementation(_transformationContext, AspectWeaver.AspectInfrastructureTask, context);
     methodWrapper.Execute();
 }
Пример #17
0
 public override void Implement(MethodBodyTransformationContext context)
 {
     context.InstructionBlock.MethodBody.Visit(new[] { new Visitor(this, context) });
 }
Пример #18
0
 public Visitor(Instance instance, MethodBodyTransformationContext context)
 {
     this.instance = instance;
     this.context = context;
 }
                public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context)
                    : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context)
                {
                    this.transformationInstance = transformationInstance;
                    this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance);

                    // todo fix configuration
                    this.onEntryOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnEntryOptions);
                    this.onSuccessOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnSuccessOptions);
                    this.onExceptionOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnExceptionOptions);
                }
                public override void Implement(MethodBodyTransformationContext context)
                {
                    /* We want to generate the following
                     *  if ( !this.<>4__this.Dispatcher.CheckAccess() )
                     *   {
                     *      SynchronizationContext oldContext = SynchronizationContext.Current;
                     *      SynchronizationContext.SetSynchronizationContext( this.<>4__this.Dispatcher.SynchronizationContext );
                     *      this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter();
                     *      this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                     *      SynchronizationContext.SetSynchronizationContext( oldContext );
                     *      return;
                     *   }
                     *
                     */



                    MethodDefDeclaration targetMethod = (MethodDefDeclaration)context.TargetElement;
                    TypeDefDeclaration   targetType   = targetMethod.DeclaringType;

                    targetMethod.MethodBody.MaxStack = -1;

                    // Add the field where we will store the awaiter.
                    FieldDefDeclaration awaiterFieldDef = new FieldDefDeclaration
                    {
                        Name       = "<>t__dispatchAwaiter",
                        FieldType  = this.parent.yieldAwaiter_Type,
                        Attributes = FieldAttributes.Private
                    };

                    targetType.Fields.Add(awaiterFieldDef);
                    IField awaiterField = awaiterFieldDef.GetCanonicalGenericInstance();

                    // Find other fields.
                    IField thisField    = targetType.Fields.Single <FieldDefDeclaration>(f => f.Name.EndsWith("__this")).GetCanonicalGenericInstance();
                    IField builderField = targetType.Fields.GetByName("<>t__builder").GetCanonicalGenericInstance();

                    // Emit instructions.
                    InstructionBlock myBlock    = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);
                    InstructionBlock theirBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);

                    LocalVariableSymbol awaitableLocal = myBlock.DefineLocalVariable(this.parent.task_Yield_Method.ReturnType, "awaitable");
                    LocalVariableSymbol synchronizationContextLocal = myBlock.DefineLocalVariable(this.parent.synchronizationContext_Type, "oldContext");

                    InstructionSequence entrySequence = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionSequence exitSequence  = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionWriter   writer        = new InstructionWriter();

                    writer.AttachInstructionSequence(entrySequence);

                    // Emit: if ( this.<>4__this.Dispatcher.CheckAccess() ) goto exitSequence;
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_CheckAccess_Method);
                    writer.EmitBranchingInstruction(OpCodeNumber.Brtrue, exitSequence);

                    // Emit: this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter()
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.task_Yield_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, awaitableLocal);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloca, awaitableLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.yieldAwaitable_GetAwaiter_Method);
                    writer.EmitInstructionField(OpCodeNumber.Stfld, awaiterField);

                    // Emit: oldContext = SynchronizationContext.Current
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_getCurrent_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, synchronizationContextLocal);

                    // Emit: SynchronizationContext.SetSynchronizationContext(this.<>4__this.Dispatcher.SynchronizationContext)
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_getSynchronizationContext_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);

                    // Choose which AwaitUnsafeOnCompleted method to call.
                    IGenericMethodDefinition awaitUnsafeOnCompletedMethod;

                    ITypeSignature[] awaitUnsafeOnCompletedGenericTypeParameters;
                    if (builderField.FieldType == this.parent.asyncVoidMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncVoidMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else if (builderField.FieldType == this.parent.asyncTaskMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else
                    {
                        // This is a generic task.
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilderGeneric_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters =
                            builderField.FieldType.GetGenericContext(GenericContextOptions.None).GetGenericTypeParameters();
                    }

                    IMethod awaitUnsafeOnCompletedGenericMethod =
                        awaitUnsafeOnCompletedMethod.GetGenericInstance(new GenericMap(awaitUnsafeOnCompletedGenericTypeParameters,
                                                                                       new ITypeSignature[]
                    {
                        this.parent.yieldAwaiter_Type,
                        targetType.GetCanonicalGenericInstance()
                    }));

                    // Emit: this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, builderField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, awaiterField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, awaitUnsafeOnCompletedGenericMethod);

                    // Emit: SynchronizationContext.SetSynchronizationContext( oldContext );
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, synchronizationContextLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);


                    writer.EmitBranchingInstruction(OpCodeNumber.Leave, context.LeaveBranchTarget);

                    writer.DetachInstructionSequence();

                    // We are done. Give the pipeline to the next node.
                    context.AddRedirection(theirBlock, context.LeaveBranchTarget);
                }